diff options
| -rw-r--r-- | content/common/BUILD.gn | 8 | ||||
| -rw-r--r-- | content/common/gpu/media/v4l2_slice_video_decode_accelerator.cc | 2 | ||||
| -rw-r--r-- | content/common/gpu/media/vaapi_video_decode_accelerator.cc | 304 | ||||
| -rw-r--r-- | content/common/gpu/media/vaapi_video_decode_accelerator.h | 7 | ||||
| -rw-r--r-- | content/common/gpu/media/vaapi_wrapper.cc | 1 | ||||
| -rw-r--r-- | content/common/gpu/media/video_decode_accelerator_unittest.cc | 4 | ||||
| -rw-r--r-- | content/common/gpu/media/vp8_picture.cc | 4 | ||||
| -rw-r--r-- | content/common/gpu/media/vp8_picture.h | 2 | ||||
| -rw-r--r-- | content/content_common.gypi | 8 | ||||
| -rw-r--r-- | media/test/data/test-25fps.vp8.md5 | 2 |
10 files changed, 324 insertions, 18 deletions
diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn index 6816544..25627f1 100644 --- a/content/common/BUILD.gn +++ b/content/common/BUILD.gn @@ -342,6 +342,10 @@ source_set("common") { "gpu/media/h264_decoder.h", "gpu/media/h264_dpb.cc", "gpu/media/h264_dpb.h", + "gpu/media/vp8_decoder.cc", + "gpu/media/vp8_decoder.h", + "gpu/media/vp8_picture.cc", + "gpu/media/vp8_picture.h", ] if (use_v4lplugin) { defines += [ "USE_LIBV4L2" ] @@ -363,10 +367,6 @@ source_set("common") { "gpu/media/v4l2_video_decode_accelerator.h", "gpu/media/v4l2_video_encode_accelerator.cc", "gpu/media/v4l2_video_encode_accelerator.h", - "gpu/media/vp8_decoder.cc", - "gpu/media/vp8_decoder.h", - "gpu/media/vp8_picture.cc", - "gpu/media/vp8_picture.h", ] libs = [ "EGL", diff --git a/content/common/gpu/media/v4l2_slice_video_decode_accelerator.cc b/content/common/gpu/media/v4l2_slice_video_decode_accelerator.cc index cff95f3..342be1a 100644 --- a/content/common/gpu/media/v4l2_slice_video_decode_accelerator.cc +++ b/content/common/gpu/media/v4l2_slice_video_decode_accelerator.cc @@ -296,7 +296,7 @@ class V4L2SliceVideoDecodeAccelerator::V4L2VP8Accelerator V4L2VP8Accelerator(V4L2SliceVideoDecodeAccelerator* v4l2_dec); ~V4L2VP8Accelerator() override; - // H264Decoder::VP8Accelerator implementation. + // VP8Decoder::VP8Accelerator implementation. scoped_refptr<VP8Picture> CreateVP8Picture() override; bool SubmitDecode(const scoped_refptr<VP8Picture>& pic, diff --git a/content/common/gpu/media/vaapi_video_decode_accelerator.cc b/content/common/gpu/media/vaapi_video_decode_accelerator.cc index 060c87d..1a46f1e 100644 --- a/content/common/gpu/media/vaapi_video_decode_accelerator.cc +++ b/content/common/gpu/media/vaapi_video_decode_accelerator.cc @@ -15,8 +15,10 @@ #include "content/common/gpu/media/accelerated_video_decoder.h" #include "content/common/gpu/media/h264_decoder.h" #include "content/common/gpu/media/vaapi_picture.h" +#include "content/common/gpu/media/vp8_decoder.h" #include "media/base/bind_to_current_loop.h" #include "media/video/picture.h" +#include "third_party/libva/va/va_dec_vp8.h" #include "ui/gl/gl_bindings.h" #include "ui/gl/gl_image.h" @@ -142,6 +144,60 @@ class VaapiVideoDecodeAccelerator::VaapiH264Accelerator DISALLOW_COPY_AND_ASSIGN(VaapiH264Accelerator); }; +class VaapiVP8Picture : public VP8Picture { + public: + VaapiVP8Picture(const scoped_refptr< + VaapiVideoDecodeAccelerator::VaapiDecodeSurface>& dec_surface); + + VaapiVP8Picture* AsVaapiVP8Picture() override { return this; } + scoped_refptr<VaapiVideoDecodeAccelerator::VaapiDecodeSurface> dec_surface() { + return dec_surface_; + } + + private: + ~VaapiVP8Picture() override; + + scoped_refptr<VaapiVideoDecodeAccelerator::VaapiDecodeSurface> dec_surface_; + + DISALLOW_COPY_AND_ASSIGN(VaapiVP8Picture); +}; + +VaapiVP8Picture::VaapiVP8Picture(const scoped_refptr< + VaapiVideoDecodeAccelerator::VaapiDecodeSurface>& dec_surface) + : dec_surface_(dec_surface) { +} + +VaapiVP8Picture::~VaapiVP8Picture() { +} + +class VaapiVideoDecodeAccelerator::VaapiVP8Accelerator + : public VP8Decoder::VP8Accelerator { + public: + VaapiVP8Accelerator(VaapiVideoDecodeAccelerator* vaapi_dec, + VaapiWrapper* vaapi_wrapper); + ~VaapiVP8Accelerator() override; + + // VP8Decoder::VP8Accelerator implementation. + scoped_refptr<VP8Picture> CreateVP8Picture() override; + + bool SubmitDecode(const scoped_refptr<VP8Picture>& pic, + const media::Vp8FrameHeader* frame_hdr, + const scoped_refptr<VP8Picture>& last_frame, + const scoped_refptr<VP8Picture>& golden_frame, + const scoped_refptr<VP8Picture>& alt_frame) override; + + bool OutputPicture(const scoped_refptr<VP8Picture>& pic) override; + + private: + scoped_refptr<VaapiDecodeSurface> VP8PictureToVaapiDecodeSurface( + const scoped_refptr<VP8Picture>& pic); + + VaapiWrapper* vaapi_wrapper_; + VaapiVideoDecodeAccelerator* vaapi_dec_; + + DISALLOW_COPY_AND_ASSIGN(VaapiVP8Accelerator); +}; + VaapiVideoDecodeAccelerator::InputBuffer::InputBuffer() : id(0), size(0) { } @@ -237,15 +293,19 @@ bool VaapiVideoDecodeAccelerator::Initialize(media::VideoCodecProfile profile, return false; } - if (!(profile >= media::H264PROFILE_MIN && - profile <= media::H264PROFILE_MAX)) { + if (profile >= media::H264PROFILE_MIN && profile <= media::H264PROFILE_MAX) { + h264_accelerator_.reset( + new VaapiH264Accelerator(this, vaapi_wrapper_.get())); + decoder_.reset(new H264Decoder(h264_accelerator_.get())); + } else if (profile >= media::VP8PROFILE_MIN && + profile <= media::VP8PROFILE_MAX) { + vp8_accelerator_.reset(new VaapiVP8Accelerator(this, vaapi_wrapper_.get())); + decoder_.reset(new VP8Decoder(vp8_accelerator_.get())); + } else { DLOG(ERROR) << "Unsupported profile " << profile; return false; } - h264_accelerator_.reset(new VaapiH264Accelerator(this, vaapi_wrapper_.get())); - decoder_.reset(new H264Decoder(h264_accelerator_.get())); - CHECK(decoder_thread_.Start()); decoder_thread_proxy_ = decoder_thread_.message_loop_proxy(); @@ -1215,6 +1275,240 @@ int VaapiVideoDecodeAccelerator::VaapiH264Accelerator::FillVARefFramesFromDPB( return i; } +VaapiVideoDecodeAccelerator::VaapiVP8Accelerator::VaapiVP8Accelerator( + VaapiVideoDecodeAccelerator* vaapi_dec, + VaapiWrapper* vaapi_wrapper) + : vaapi_wrapper_(vaapi_wrapper), vaapi_dec_(vaapi_dec) { + DCHECK(vaapi_wrapper_); + DCHECK(vaapi_dec_); +} + +VaapiVideoDecodeAccelerator::VaapiVP8Accelerator::~VaapiVP8Accelerator() { +} + +scoped_refptr<VP8Picture> +VaapiVideoDecodeAccelerator::VaapiVP8Accelerator::CreateVP8Picture() { + scoped_refptr<VaapiDecodeSurface> va_surface = vaapi_dec_->CreateSurface(); + if (!va_surface) + return nullptr; + + return new VaapiVP8Picture(va_surface); +} + +#define ARRAY_MEMCPY_CHECKED(to, from) \ + do { \ + static_assert(sizeof(to) == sizeof(from), \ + #from " and " #to " arrays must be of same size"); \ + memcpy(to, from, sizeof(to)); \ + } while (0) + +bool VaapiVideoDecodeAccelerator::VaapiVP8Accelerator::SubmitDecode( + const scoped_refptr<VP8Picture>& pic, + const media::Vp8FrameHeader* frame_hdr, + const scoped_refptr<VP8Picture>& last_frame, + const scoped_refptr<VP8Picture>& golden_frame, + const scoped_refptr<VP8Picture>& alt_frame) { + VAIQMatrixBufferVP8 iq_matrix_buf; + memset(&iq_matrix_buf, 0, sizeof(VAIQMatrixBufferVP8)); + + const media::Vp8SegmentationHeader& sgmnt_hdr = frame_hdr->segmentation_hdr; + const media::Vp8QuantizationHeader& quant_hdr = frame_hdr->quantization_hdr; + static_assert( + arraysize(iq_matrix_buf.quantization_index) == media::kMaxMBSegments, + "incorrect quantization matrix size"); + for (size_t i = 0; i < media::kMaxMBSegments; ++i) { + int q = quant_hdr.y_ac_qi; + + if (sgmnt_hdr.segmentation_enabled) { + if (sgmnt_hdr.segment_feature_mode == + media::Vp8SegmentationHeader::FEATURE_MODE_ABSOLUTE) + q = sgmnt_hdr.quantizer_update_value[i]; + else + q += sgmnt_hdr.quantizer_update_value[i]; + } + +#define CLAMP_Q(q) std::min(std::max(q, 0), 127) + static_assert(arraysize(iq_matrix_buf.quantization_index[i]) == 6, + "incorrect quantization matrix size"); + iq_matrix_buf.quantization_index[i][0] = CLAMP_Q(q); + iq_matrix_buf.quantization_index[i][1] = CLAMP_Q(q + quant_hdr.y_dc_delta); + iq_matrix_buf.quantization_index[i][2] = CLAMP_Q(q + quant_hdr.y2_dc_delta); + iq_matrix_buf.quantization_index[i][3] = CLAMP_Q(q + quant_hdr.y2_ac_delta); + iq_matrix_buf.quantization_index[i][4] = CLAMP_Q(q + quant_hdr.uv_dc_delta); + iq_matrix_buf.quantization_index[i][5] = CLAMP_Q(q + quant_hdr.uv_ac_delta); +#undef CLAMP_Q + } + + if (!vaapi_wrapper_->SubmitBuffer(VAIQMatrixBufferType, + sizeof(VAIQMatrixBufferVP8), + &iq_matrix_buf)) + return false; + + VAProbabilityDataBufferVP8 prob_buf; + memset(&prob_buf, 0, sizeof(VAProbabilityDataBufferVP8)); + + const media::Vp8EntropyHeader& entr_hdr = frame_hdr->entropy_hdr; + ARRAY_MEMCPY_CHECKED(prob_buf.dct_coeff_probs, entr_hdr.coeff_probs); + + if (!vaapi_wrapper_->SubmitBuffer(VAProbabilityBufferType, + sizeof(VAProbabilityDataBufferVP8), + &prob_buf)) + return false; + + VAPictureParameterBufferVP8 pic_param; + memset(&pic_param, 0, sizeof(VAPictureParameterBufferVP8)); + pic_param.frame_width = frame_hdr->width; + pic_param.frame_height = frame_hdr->height; + + if (last_frame) { + scoped_refptr<VaapiDecodeSurface> last_frame_surface = + VP8PictureToVaapiDecodeSurface(last_frame); + pic_param.last_ref_frame = last_frame_surface->va_surface()->id(); + } else { + pic_param.last_ref_frame = VA_INVALID_SURFACE; + } + + if (golden_frame) { + scoped_refptr<VaapiDecodeSurface> golden_frame_surface = + VP8PictureToVaapiDecodeSurface(golden_frame); + pic_param.golden_ref_frame = golden_frame_surface->va_surface()->id(); + } else { + pic_param.golden_ref_frame = VA_INVALID_SURFACE; + } + + if (alt_frame) { + scoped_refptr<VaapiDecodeSurface> alt_frame_surface = + VP8PictureToVaapiDecodeSurface(alt_frame); + pic_param.alt_ref_frame = alt_frame_surface->va_surface()->id(); + } else { + pic_param.alt_ref_frame = VA_INVALID_SURFACE; + } + + pic_param.out_of_loop_frame = VA_INVALID_SURFACE; + + const media::Vp8LoopFilterHeader& lf_hdr = frame_hdr->loopfilter_hdr; + +#define FHDR_TO_PP_PF(a, b) pic_param.pic_fields.bits.a = (b); + FHDR_TO_PP_PF(key_frame, frame_hdr->IsKeyframe() ? 0 : 1); + FHDR_TO_PP_PF(version, frame_hdr->version); + FHDR_TO_PP_PF(segmentation_enabled, sgmnt_hdr.segmentation_enabled); + FHDR_TO_PP_PF(update_mb_segmentation_map, + sgmnt_hdr.update_mb_segmentation_map); + FHDR_TO_PP_PF(update_segment_feature_data, + sgmnt_hdr.update_segment_feature_data); + FHDR_TO_PP_PF(filter_type, lf_hdr.type); + FHDR_TO_PP_PF(sharpness_level, lf_hdr.sharpness_level); + FHDR_TO_PP_PF(loop_filter_adj_enable, lf_hdr.loop_filter_adj_enable); + FHDR_TO_PP_PF(mode_ref_lf_delta_update, lf_hdr.mode_ref_lf_delta_update); + FHDR_TO_PP_PF(sign_bias_golden, frame_hdr->sign_bias_golden); + FHDR_TO_PP_PF(sign_bias_alternate, frame_hdr->sign_bias_alternate); + FHDR_TO_PP_PF(mb_no_coeff_skip, frame_hdr->mb_no_skip_coeff); + FHDR_TO_PP_PF(loop_filter_disable, lf_hdr.level == 0); +#undef FHDR_TO_PP_PF + + ARRAY_MEMCPY_CHECKED(pic_param.mb_segment_tree_probs, sgmnt_hdr.segment_prob); + + static_assert(arraysize(sgmnt_hdr.lf_update_value) == + arraysize(pic_param.loop_filter_level), + "loop filter level arrays mismatch"); + for (size_t i = 0; i < arraysize(sgmnt_hdr.lf_update_value); ++i) { + int lf_level = lf_hdr.level; + if (sgmnt_hdr.segmentation_enabled) { + if (sgmnt_hdr.segment_feature_mode == + media::Vp8SegmentationHeader::FEATURE_MODE_ABSOLUTE) + lf_level = sgmnt_hdr.lf_update_value[i]; + else + lf_level += sgmnt_hdr.lf_update_value[i]; + } + + // Clamp to [0..63] range. + lf_level = std::min(std::max(lf_level, 0), 63); + pic_param.loop_filter_level[i] = lf_level; + } + + static_assert(arraysize(lf_hdr.ref_frame_delta) == + arraysize(pic_param.loop_filter_deltas_ref_frame) && + arraysize(lf_hdr.mb_mode_delta) == + arraysize(pic_param.loop_filter_deltas_mode) && + arraysize(lf_hdr.ref_frame_delta) == + arraysize(lf_hdr.mb_mode_delta), + "loop filter deltas arrays size mismatch"); + for (size_t i = 0; i < arraysize(lf_hdr.ref_frame_delta); ++i) { + pic_param.loop_filter_deltas_ref_frame[i] = lf_hdr.ref_frame_delta[i]; + pic_param.loop_filter_deltas_mode[i] = lf_hdr.mb_mode_delta[i]; + } + +#define FHDR_TO_PP(a) pic_param.a = frame_hdr->a; + FHDR_TO_PP(prob_skip_false); + FHDR_TO_PP(prob_intra); + FHDR_TO_PP(prob_last); + FHDR_TO_PP(prob_gf); +#undef FHDR_TO_PP + + ARRAY_MEMCPY_CHECKED(pic_param.y_mode_probs, entr_hdr.y_mode_probs); + ARRAY_MEMCPY_CHECKED(pic_param.uv_mode_probs, entr_hdr.uv_mode_probs); + ARRAY_MEMCPY_CHECKED(pic_param.mv_probs, entr_hdr.mv_probs); + + pic_param.bool_coder_ctx.range = frame_hdr->bool_dec_range; + pic_param.bool_coder_ctx.value = frame_hdr->bool_dec_value; + pic_param.bool_coder_ctx.count = frame_hdr->bool_dec_count; + + if (!vaapi_wrapper_->SubmitBuffer(VAPictureParameterBufferType, + sizeof(VAPictureParameterBufferVP8), + &pic_param)) + return false; + + VASliceParameterBufferVP8 slice_param; + memset(&slice_param, 0, sizeof(VASliceParameterBufferVP8)); + slice_param.slice_data_size = frame_hdr->frame_size; + slice_param.slice_data_offset = frame_hdr->first_part_offset; + slice_param.slice_data_flag = VA_SLICE_DATA_FLAG_ALL; + slice_param.macroblock_offset = frame_hdr->macroblock_bit_offset; + // Number of DCT partitions plus control partition. + slice_param.num_of_partitions = frame_hdr->num_of_dct_partitions + 1; + + // Per VAAPI, this size only includes the size of the macroblock data in + // the first partition (in bytes), so we have to subtract the header size. + slice_param.partition_size[0] = + frame_hdr->first_part_size - ((frame_hdr->macroblock_bit_offset + 7) / 8); + + for (size_t i = 0; i < frame_hdr->num_of_dct_partitions; ++i) + slice_param.partition_size[i + 1] = frame_hdr->dct_partition_sizes[i]; + + if (!vaapi_wrapper_->SubmitBuffer(VASliceParameterBufferType, + sizeof(VASliceParameterBufferVP8), + &slice_param)) + return false; + + void* non_const_ptr = const_cast<uint8*>(frame_hdr->data); + if (!vaapi_wrapper_->SubmitBuffer(VASliceDataBufferType, + frame_hdr->frame_size, + non_const_ptr)) + return false; + + scoped_refptr<VaapiDecodeSurface> dec_surface = + VP8PictureToVaapiDecodeSurface(pic); + + return vaapi_dec_->DecodeSurface(dec_surface); +} + +bool VaapiVideoDecodeAccelerator::VaapiVP8Accelerator::OutputPicture( + const scoped_refptr<VP8Picture>& pic) { + scoped_refptr<VaapiDecodeSurface> dec_surface = + VP8PictureToVaapiDecodeSurface(pic); + + vaapi_dec_->SurfaceReady(dec_surface); + return true; +} + +scoped_refptr<VaapiVideoDecodeAccelerator::VaapiDecodeSurface> +VaapiVideoDecodeAccelerator::VaapiVP8Accelerator:: + VP8PictureToVaapiDecodeSurface(const scoped_refptr<VP8Picture>& pic) { + VaapiVP8Picture* vaapi_pic = pic->AsVaapiVP8Picture(); + CHECK(vaapi_pic); + return vaapi_pic->dec_surface(); +} + // static media::VideoDecodeAccelerator::SupportedProfiles VaapiVideoDecodeAccelerator::GetSupportedProfiles() { diff --git a/content/common/gpu/media/vaapi_video_decode_accelerator.h b/content/common/gpu/media/vaapi_video_decode_accelerator.h index 5642fd3..dca54d3 100644 --- a/content/common/gpu/media/vaapi_video_decode_accelerator.h +++ b/content/common/gpu/media/vaapi_video_decode_accelerator.h @@ -72,6 +72,7 @@ class CONTENT_EXPORT VaapiVideoDecodeAccelerator private: class VaapiH264Accelerator; + class VaapiVP8Accelerator; // Notify the client that an error has occurred and decoding cannot continue. void NotifyError(Error error); @@ -271,10 +272,10 @@ class CONTENT_EXPORT VaapiVideoDecodeAccelerator scoped_ptr<base::WeakPtrFactory<Client> > client_ptr_factory_; base::WeakPtr<Client> client_; - // Comes after vaapi_wrapper_ to ensure its destructor is executed before - // vaapi_wrapper_ is destroyed. + // Accelerators come after vaapi_wrapper_ to ensure they are destroyed first. scoped_ptr<VaapiH264Accelerator> h264_accelerator_; - // After h264_accelerator_ to ensure correct destruction order. + scoped_ptr<VaapiVP8Accelerator> vp8_accelerator_; + // After *_accelerator_ to ensure correct destruction order. scoped_ptr<AcceleratedVideoDecoder> decoder_; base::Thread decoder_thread_; diff --git a/content/common/gpu/media/vaapi_wrapper.cc b/content/common/gpu/media/vaapi_wrapper.cc index 78d382e..219e370 100644 --- a/content/common/gpu/media/vaapi_wrapper.cc +++ b/content/common/gpu/media/vaapi_wrapper.cc @@ -89,6 +89,7 @@ static const ProfileMap kProfileMap[] = { // TODO(posciak): See if we can/want support other variants of // media::H264PROFILE_HIGH*. {media::H264PROFILE_HIGH, VAProfileH264High}, + {media::VP8PROFILE_ANY, VAProfileVP8Version0_3}, }; static std::vector<VAConfigAttrib> GetRequiredAttribs( diff --git a/content/common/gpu/media/video_decode_accelerator_unittest.cc b/content/common/gpu/media/video_decode_accelerator_unittest.cc index be59e0d..057c79b 100644 --- a/content/common/gpu/media/video_decode_accelerator_unittest.cc +++ b/content/common/gpu/media/video_decode_accelerator_unittest.cc @@ -197,7 +197,9 @@ void ReadGoldenThumbnailMD5s(const TestVideoFile* video_file, kMD5StringLength; CHECK(hex_only) << *md5_string; } - CHECK_GE(md5_strings->size(), 1U) << all_md5s; + CHECK_GE(md5_strings->size(), 1U) << " MD5 checksum file (" + << filepath.MaybeAsASCII() + << ") missing or empty."; } // State of the GLRenderingVDAClient below. Order matters here as the test diff --git a/content/common/gpu/media/vp8_picture.cc b/content/common/gpu/media/vp8_picture.cc index 764c3b1..63ec8e9 100644 --- a/content/common/gpu/media/vp8_picture.cc +++ b/content/common/gpu/media/vp8_picture.cc @@ -16,4 +16,8 @@ V4L2VP8Picture* VP8Picture::AsV4L2VP8Picture() { return nullptr; } +VaapiVP8Picture* VP8Picture::AsVaapiVP8Picture() { + return nullptr; +} + } // namespace content diff --git a/content/common/gpu/media/vp8_picture.h b/content/common/gpu/media/vp8_picture.h index 1187698..eb8307f 100644 --- a/content/common/gpu/media/vp8_picture.h +++ b/content/common/gpu/media/vp8_picture.h @@ -10,12 +10,14 @@ namespace content { class V4L2VP8Picture; +class VaapiVP8Picture; class VP8Picture : public base::RefCounted<VP8Picture> { public: VP8Picture(); virtual V4L2VP8Picture* AsV4L2VP8Picture(); + virtual VaapiVP8Picture* AsVaapiVP8Picture(); protected: friend class base::RefCounted<VP8Picture>; diff --git a/content/content_common.gypi b/content/content_common.gypi index 1b8e808..f989b37 100644 --- a/content/content_common.gypi +++ b/content/content_common.gypi @@ -829,6 +829,10 @@ 'common/gpu/media/h264_decoder.h', 'common/gpu/media/h264_dpb.cc', 'common/gpu/media/h264_dpb.h', + 'common/gpu/media/vp8_decoder.cc', + 'common/gpu/media/vp8_decoder.h', + 'common/gpu/media/vp8_picture.cc', + 'common/gpu/media/vp8_picture.h', ], }], ['chromeos==1 and use_v4l2_codec==1', { @@ -856,10 +860,6 @@ 'common/gpu/media/v4l2_video_decode_accelerator.h', 'common/gpu/media/v4l2_video_encode_accelerator.cc', 'common/gpu/media/v4l2_video_encode_accelerator.h', - 'common/gpu/media/vp8_decoder.cc', - 'common/gpu/media/vp8_decoder.h', - 'common/gpu/media/vp8_picture.cc', - 'common/gpu/media/vp8_picture.h', ], 'include_dirs': [ '<(DEPTH)/third_party/khronos', diff --git a/media/test/data/test-25fps.vp8.md5 b/media/test/data/test-25fps.vp8.md5 index fb3183a..6ae8188 100644 --- a/media/test/data/test-25fps.vp8.md5 +++ b/media/test/data/test-25fps.vp8.md5 @@ -2,3 +2,5 @@ 10144053d714f6429efd266710513584 # ARM - Tegra cd355b553ce7660283c52675232e9227 +# Intel - BDW +4da7ec5484a99195c2c05b5e591940f9 |
