diff options
author | Hendrik Leppkes <h.leppkes@gmail.com> | 2017-04-18 17:37:47 +0300 |
---|---|---|
committer | Hendrik Leppkes <h.leppkes@gmail.com> | 2017-04-18 17:38:38 +0300 |
commit | 8da3109e4cca9ea769d56e924268388b1a069814 (patch) | |
tree | d7700f0173d5a2cfe005b3e0fa538214f0ed19df /demuxer | |
parent | fc03ae938f64c553497e754d38bd219aec924846 (diff) |
Generate VP8/9 extradata with profile and color information
This information is modeled after the latest draft of the VP Codec in
ISO Media specification (ie. VP8/9 in MP4).
Diffstat (limited to 'demuxer')
-rw-r--r-- | demuxer/Demuxers/LAVFStreamInfo.cpp | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/demuxer/Demuxers/LAVFStreamInfo.cpp b/demuxer/Demuxers/LAVFStreamInfo.cpp index 4dd58f95..b0f8323e 100644 --- a/demuxer/Demuxers/LAVFStreamInfo.cpp +++ b/demuxer/Demuxers/LAVFStreamInfo.cpp @@ -199,6 +199,35 @@ static bool hevc_is_annexb(std::string format, AVStream *avstream) return true; } +static int get_vpcC_chroma(AVCodecParameters *codecpar) +{ + int chroma_w = 0, chroma_h = 0; + if (av_pix_fmt_get_chroma_sub_sample((AVPixelFormat)codecpar->format, &chroma_w, &chroma_h) == 0) { + if (chroma_w == 1 && chroma_h == 1) { + return (codecpar->chroma_location == AVCHROMA_LOC_LEFT) + ? 0 + : 1; + } + else if (chroma_w == 1 && chroma_h == 0) { + return 2; + } + else if (chroma_w == 0 && chroma_h == 0) { + return 3; + } + } + return 0; +} + +static int get_pixel_bitdepth(AVPixelFormat pix_fmt) +{ + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); + if (desc == NULL) { + DbgLog((LOG_TRACE, 10, "Unknown pixel format")); + return 8; + } + return desc->comp[0].depth; +} + STDMETHODIMP CLAVFStreamInfo::CreateVideoMediaType(AVFormatContext *avctx, AVStream *avstream) { unsigned int origCodecTag = avstream->codecpar->codec_tag; @@ -261,6 +290,23 @@ STDMETHODIMP CLAVFStreamInfo::CreateVideoMediaType(AVFormatContext *avctx, AVStr VIDEOINFOHEADER2 *vih2 = (VIDEOINFOHEADER2 *)mtype.pbFormat; vih2->bmiHeader.biCompression = mtype.subtype.Data1; } + else if (mtype.subtype == MEDIASUBTYPE_VP90) { + // generate extradata for VP9 streams + mtype.ReallocFormatBuffer(sizeof(VIDEOINFOHEADER2) + 15); + VIDEOINFOHEADER2 *vih2 = (VIDEOINFOHEADER2 *)mtype.pbFormat; + vih2->bmiHeader.biSize = sizeof(BITMAPINFOHEADER) + 15; + + BYTE *extra = mtype.pbFormat + sizeof(VIDEOINFOHEADER2); + AV_WL32(extra, MKTAG('v', 'p', 'c', 'C')); + AV_WL32(extra + 4, 0); // version & flags + AV_WL8 (extra + 8, avstream->codecpar->profile); + AV_WL8 (extra + 9, avstream->codecpar->level == FF_LEVEL_UNKNOWN ? 0 : avstream->codecpar->level); + AV_WL8 (extra + 10, get_pixel_bitdepth((AVPixelFormat)avstream->codecpar->format) << 4 | get_vpcC_chroma(avstream->codecpar) << 1 | (avstream->codecpar->color_range == AVCOL_RANGE_JPEG)); + AV_WL8 (extra + 11, avstream->codecpar->color_primaries); + AV_WL8 (extra + 12, avstream->codecpar->color_trc); + AV_WL8 (extra + 13, avstream->codecpar->color_space); + AV_WL16(extra + 14, 0); // no codec init data + } } else if (mtype.formattype == FORMAT_MPEGVideo) { mtype.pbFormat = (BYTE *)g_VideoHelper.CreateMPEG1VI(avstream, &mtype.cbFormat, m_containerFormat); } else if (mtype.formattype == FORMAT_MPEG2Video) { |