[FFmpeg-devel] [PATCH 1/3] avformat/mxfenc: H.264 Intra support

Tomas Härdin tomas.hardin at codemill.se
Wed Sep 24 21:59:17 CEST 2014


On Sat, 2014-09-13 at 12:36 +0200, Michael Niedermayer wrote:
> From: Baptiste Coudurier <baptiste.coudurier at gmail.com>
> 
> Ported by michael from ffmbc to ffmpeg
> the code is under CONFIG_GPL as ffmbc is GPL
> 
> Signed-off-by: Michael Niedermayer <michaelni at gmx.at>
> ---
>  libavformat/mxfenc.c |  143 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 143 insertions(+)

> +static int mxf_parse_h264_frame(AVFormatContext *s, AVStream *st,
> +                                AVPacket *pkt, MXFIndexEntry *e)
> +{
> +    MXFStreamContext *sc = st->priv_data;
> +    H264Context h;
> +    const uint8_t *buf = pkt->data;
> +    const uint8_t *buf_end = pkt->data + pkt->size;
> +    uint32_t state = -1;
> +    AVRational sar = {1, 1};
> +
> +    if (pkt->size < 5 || AV_RB32(pkt->data) != 0x0000001) {
> +        av_log(s, AV_LOG_ERROR, "h264 bitstream malformated, "
> +               "no startcode found, use -vbsf h264_mp4toannexb\n");
> +        return 0;
> +    }
> +
> +    memset(&h, 0, sizeof(h));
> +    h.avctx = st->codec;
> +    h.thread_context[0] = &h;
> +    h.prev_frame_num = -1;
> +
> +    for (;;) {
> +        int src_length, dst_length, consumed;
> +        const uint8_t *ptr;
> +
> +        buf = avpriv_find_start_code(buf, buf_end, &state);
> +        if (buf >= buf_end)
> +            break;
> +        --buf;
> +        src_length = buf_end - buf;
> +        switch (state & 0x1f) {
> +        case NAL_SLICE:
> +        case NAL_IDR_SLICE:
> +            // Do not walk the whole buffer just to decode slice header
> +            if (src_length > 20)
> +                src_length = 20;
> +            break;
> +        }
> +
> +        ptr = ff_h264_decode_nal(&h, buf, &dst_length, &consumed, src_length);
> +        if (!ptr || dst_length < 0)
> +            break;
> +
> +        init_get_bits(&h.gb, ptr, 8*dst_length);
> +        //av_log(avctx, AV_LOG_DEBUG, "nal_unit_type:%d\n", h.nal_unit_type);
> +        switch (h.nal_unit_type) {
> +        case NAL_SPS:
> +            ff_h264_decode_seq_parameter_set(&h);
> +            if (h.sps.sar.num > 0 && h.sps.sar.den > 0) {
> +                sar.num = st->codec->width * h.sps.sar.num;
> +                sar.den = st->codec->height * h.sps.sar.den;
> +            }
> +            sc->aspect_ratio.num = st->codec->width * sar.num;
> +            sc->aspect_ratio.den = st->codec->height * sar.den;
> +            av_reduce(&sc->aspect_ratio.num, &sc->aspect_ratio.den,
> +                      sar.num, sar.den, 1024*1024);
> +
> +            sc->interlaced = !h.sps.frame_mbs_only_flag;
> +            sc->component_depth = h.sps.bit_depth_luma;
> +
> +            sc->codec_ul = mxf_get_h264_codec_ul(st->codec, &h.sps);
> +            e->flags |= 0x40;
> +            break;
> +        case NAL_PPS:
> +            ff_h264_decode_picture_parameter_set(&h, h.gb.size_in_bits);
> +            if (h.sps.timing_info_present_flag) {
> +                if (st->codec->time_base.num != h.sps.num_units_in_tick ||
> +                    st->codec->time_base.den*2 != h.sps.time_scale) {
> +                    av_log(s, AV_LOG_ERROR, "framerate does not match bitstream values: %d/%d != %d/%d\n",
> +                           h.sps.num_units_in_tick, h.sps.time_scale, st->codec->time_base.num, st->codec->time_base.den*2);
> +                    return 0;
> +                }
> +            }
> +            if (e->flags & 0x40) // sequence header present
> +                e->flags |= 0x80; // random access
> +            break;
> +        case NAL_IDR_SLICE:
> +            break;
> +        case NAL_SLICE:
> +            av_log(s, AV_LOG_ERROR, "mxf muxer only supports AVC Intra currently\n");
> +            return 0;
> +        }
> +    }
> +
> +    return !!sc->codec_ul;
> +}

Seems awfully specific code to have in a muxer. Can this be reused
elsewhere? Don't let that stop you though.

Overall I'm OK with this patch being GPL. It's not optimal, but I
compile with libx264 for my own purposes anyway and thus have GPL
enabled. If someone wants it LGPL bad enough then they're free to
rewrite this of course. Perhaps as a part of making the functionality of
the above function reusable elsewhere? (I think MOV might support
AVC-Intra)

/Tomas
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: This is a digitally signed message part
URL: <https://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20140924/716c92b8/attachment.asc>


More information about the ffmpeg-devel mailing list