[FFmpeg-devel] DVR MPEG4 variant (AS-3024)

Ivo Andonov ivo.andonov at gmail.com
Fri Feb 3 18:11:56 EET 2017


2017-02-03 17:54 GMT+02:00 Ivo Andonov <ivo.andonov at gmail.com>:

> 2017-02-03 16:59 GMT+02:00 Carl Eugen Hoyos <ceffmpeg at gmail.com>:
>
>> 2017-02-03 15:14 GMT+01:00 Ivo Andonov <ivo.andonov at gmail.com>:
>> > 2017-02-03 15:58 GMT+02:00 Carl Eugen Hoyos <ceffmpeg at gmail.com>:
>>
>> >> > I've got some old Pinetron DVRs that are supposed to produce a MPEG4
>> >> > bitstream. Indeed they are but no non-Pinetron software can decode
>> it.
>> >>
>> >> Please provide a sample!
>> >>
>> >> > I do now know what is the best approach for registering this as a new
>> >> > decoder
>> >>
>> >> It should be possible to identify the codec while reading the
>> bitstream.
>>
>> The encoder sets no user data, so identification is not as simple as
>> hoped: How do subsequent frames start? Do you know what the
>> first bytes mean?
>>
>>
> Yes, no user data is set and as such automatic identification is not
> possible. The raw stream coming from the DVR is prefixed by a propriatory
> frame header (that I filter) which is not MPEG stream compliant and is
> meant for the viewer/recorder (timestamp, keyframe flag, frame data size
> etc).
>
> So far I'm attempting to implement the decoding by explicitly specifing to
> ffmpeg the video codec to use (-vcodec xvid_alogics). xvid_alogics AVCodec
> is initialized the same way the mpeg4 one, just a different id. In the
> decode_init I change the avctx->codec_id to AV_CODEC_ID_MPEG4 and set a
> flag in workaround_bugs that I later use in the initially submitted block
> condition code.
> However it seems somewhere else in the code avctx->codec_id reverts back
> to avctx->codec->id and as a result I end up with a "Bad picture start
> code" due to ff_h263_decode_frame calling ff_h263_decode_picture_header
> instead of ff_mpeg4_decode_picture_header.
> I forgot to mention that my changes are against ffmpeg 2.6. (libavcodec
> 56.26.100)
>
>

I do not know if this is the best approach but I ended up with:

mpeg4videodec.c:

static av_cold int alogics_decode_init(AVCodecContext *avctx) {
   avctx->workaround_bugs |= FF_BUG_ALOGICS;
   return decode_init(avctx);
}

and

AVCodec ff_xvid_alogics_decoder = {
    .name                  = "xvid_alogics",
    .long_name             = NULL_IF_CONFIG_SMALL("XVID Alogics"),
    .type                  = AVMEDIA_TYPE_VIDEO,
    .id                    = AV_CODEC_ID_MPEG4,
    .priv_data_size        = sizeof(Mpeg4DecContext),
    .init                  = alogics_decode_init,
    .close                 = ff_h263_decode_end,
    .decode                = ff_h263_decode_frame,
    .capabilities          = CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 |
                             CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY |
                             CODEC_CAP_FRAME_THREADS,
    .flush                 = ff_mpeg_flush,
    .max_lowres            = 3,
    .pix_fmts              = ff_h263_hwaccel_pixfmt_list_420,
    .profiles              = NULL_IF_CONFIG_SMALL(mpeg4_video_profiles),
    .update_thread_context =
ONLY_IF_THREADS_ENABLED(mpeg4_update_thread_context),
    .priv_class = &mpeg4_class,
};

Then the block of code in mpeg4video.h before pred = FASTDIV is enclosed in
an if-else of:

    if (s->workaround_bugs & FF_BUG_ALOGICS) {
      //new code
    } else {
      //original code
    }

Ivo


More information about the ffmpeg-devel mailing list