Commit ffa5c05c authored by Sreerenj Balachandran's avatar Sreerenj Balachandran Committed by Commit Bot

media: Add H264 profile extraction support

Without the ffmpeg decoder configured, libavformat is unable to get the
codec profile and chromium ffmpeg wrapper code choose some defaults.
This will mess up the decode scenarios where non-ffmpeg decoders like vaapi
are in use. Fortunately, we can still get hold of the ffmpeg's
AVStream extradata param which should contain the
H264 AVCDecoderConfigurationRecord (ISO/IEC 14496-15).
So we use internal parser for extracting profile information
from this AVCDecoderConfigurationRecord.

BUG=784610
TEST=media_unittests:FFmpegCommonTest.VerifyH264Profile

Change-Id: Id67c7026eefb5bb73e6c5fbbab7a362cb4553ab1
Reviewed-on: https://chromium-review.googlesource.com/c/1292605
Commit-Queue: Chrome Cunningham <chcunningham@chromium.org>
Reviewed-by: default avatarDale Curtis <dalecurtis@chromium.org>
Reviewed-by: default avatarChrome Cunningham <chcunningham@chromium.org>
Cr-Commit-Position: refs/heads/master@{#607769}
parent a0ef725b
...@@ -30,6 +30,7 @@ source_set("ffmpeg") { ...@@ -30,6 +30,7 @@ source_set("ffmpeg") {
deps = [ deps = [
"//base", "//base",
"//media/base", "//media/base",
"//media/formats",
"//third_party/ffmpeg", "//third_party/ffmpeg",
"//third_party/ffmpeg:ffmpeg_features", "//third_party/ffmpeg:ffmpeg_features",
] ]
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "media/base/media_util.h" #include "media/base/media_util.h"
#include "media/base/video_decoder_config.h" #include "media/base/video_decoder_config.h"
#include "media/base/video_util.h" #include "media/base/video_util.h"
#include "media/formats/mp4/box_definitions.h"
#include "media/media_buildflags.h" #include "media/media_buildflags.h"
namespace media { namespace media {
...@@ -479,12 +480,27 @@ bool AVStreamToVideoDecoderConfig(const AVStream* stream, ...@@ -479,12 +480,27 @@ bool AVStreamToVideoDecoderConfig(const AVStream* stream,
// actually handle capabilities requests correctly. http://crbug.com/784610 // actually handle capabilities requests correctly. http://crbug.com/784610
VideoCodecProfile profile = VIDEO_CODEC_PROFILE_UNKNOWN; VideoCodecProfile profile = VIDEO_CODEC_PROFILE_UNKNOWN;
switch (codec) { switch (codec) {
#if !BUILDFLAG(ENABLE_FFMPEG_VIDEO_DECODERS) case kCodecH264: {
case kCodecH264: profile = ProfileIDToVideoCodecProfile(codec_context->profile);
#if BUILDFLAG(USE_PROPRIETARY_CODECS)
// if the profile is still unknown, try to extract it from
// the extradata using the internal parser
if (profile == VIDEO_CODEC_PROFILE_UNKNOWN && codec_context->extradata &&
codec_context->extradata_size) {
mp4::AVCDecoderConfigurationRecord avc_config;
if (avc_config.Parse(codec_context->extradata,
codec_context->extradata_size)) {
profile = ProfileIDToVideoCodecProfile(avc_config.profile_indication);
}
}
#endif
// All the heuristics failed, let's assign a default profile
if (profile == VIDEO_CODEC_PROFILE_UNKNOWN)
profile = H264PROFILE_BASELINE;
format = PIXEL_FORMAT_I420; format = PIXEL_FORMAT_I420;
profile = H264PROFILE_BASELINE;
break; break;
#endif }
case kCodecVP8: case kCodecVP8:
#if !BUILDFLAG(ENABLE_FFMPEG_VIDEO_DECODERS) #if !BUILDFLAG(ENABLE_FFMPEG_VIDEO_DECODERS)
format = PIXEL_FORMAT_I420; format = PIXEL_FORMAT_I420;
......
...@@ -296,5 +296,31 @@ TEST_F(FFmpegCommonTest, VerifyUmaCodecHashes) { ...@@ -296,5 +296,31 @@ TEST_F(FFmpegCommonTest, VerifyUmaCodecHashes) {
printf("</enum>\n"); printf("</enum>\n");
#endif #endif
} }
#if BUILDFLAG(USE_PROPRIETARY_CODECS)
TEST_F(FFmpegCommonTest, VerifyH264Profile) {
// Open a file to get a real AVStreams from FFmpeg.
base::MemoryMappedFile file;
ASSERT_TRUE(file.Initialize(GetTestDataFilePath("bear-1280x720.mp4")));
InMemoryUrlProtocol protocol(file.data(), file.length(), false);
FFmpegGlue glue(&protocol);
ASSERT_TRUE(glue.OpenContext());
AVFormatContext* format_context = glue.format_context();
for (size_t i = 0; i < format_context->nb_streams; ++i) {
AVStream* stream = format_context->streams[i];
AVCodecParameters* codec_parameters = stream->codecpar;
AVMediaType codec_type = codec_parameters->codec_type;
if (codec_type == AVMEDIA_TYPE_VIDEO) {
VideoDecoderConfig video_config;
EXPECT_TRUE(AVStreamToVideoDecoderConfig(stream, &video_config));
EXPECT_EQ(H264PROFILE_HIGH, video_config.profile());
} else {
// Only process video.
continue;
}
}
}
#endif
} // namespace media } // namespace media
...@@ -14,6 +14,7 @@ source_set("formats") { ...@@ -14,6 +14,7 @@ source_set("formats") {
"//media/cdm", "//media/cdm",
"//media/filters", "//media/filters",
"//media/muxers", "//media/muxers",
"//media/ffmpeg",
] ]
sources = [ sources = [
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment