Opened 2 years ago

Last modified 22 months ago

#5838 reopened enhancement

avcodec_open2 doesn't open raw video codec unles parameters in context are set

Reported by: veroorzaker Owned by:
Priority: minor Component: documentation
Version: git-master Keywords:
Cc: Blocked By:
Blocking: Reproduced by developer: no
Analyzed by developer: no

Description

Summary of the bug:

most examples, including the one for av_codec_open2 itself and also a bunch of decoding samples like decoding_encoding.c, go like this:

codec = avcodec_find_decoder(stream->codecpar->id);
context = avcodec_alloc_context3(codec);
avcodec_open2(context, codec, opts);

However for raw video with AV_CODEC_ID_RAWVIDEO avcodec_open2 fails with error -22. It does succeed however when copying the codec parameters using for instance avcodec_parameters_to_context(context, stream->codecpar).

I'm using latest master branch and raw video created using a bunch of 64x64 bmp files:

ffmpeg -i '%d.bmp' -v:c rawvideo o.avi

Codecs like x264 do not have this problem. I think it would be nice to have this clearly mentioned in the documentation somewhere, or else have avcodec_alloc_context3 set the needed fields (width/height/extradata/extradata_size).

Change History (6)

comment:1 Changed 2 years ago by cehoyos

Please provide sample code that allows to reproduce the issue.
Are you describing a regression?

comment:2 Changed 2 years ago by cehoyos

  • Resolution set to needs_more_info
  • Status changed from new to closed

comment:3 Changed 2 years ago by veroorzaker

Apologies for the late reply, was away for a while.
Code (basically taken from avcodec_open2 documentation, but with AV_CODEC_ID_RAWVIDEO instead of AV_CODEC_ID_H264):

#include <libavformat/avformat.h>

int main(int argc, char **argv)
{
  avcodec_register_all();
  AVCodec *codec = avcodec_find_decoder(AV_CODEC_ID_RAWVIDEO);
  if (!codec) {
      return 1;
  }
  AVCodecContext *c = avcodec_alloc_context3(codec);
  if (!c) {
      return 1;
  }
  if (avcodec_open2(c, codec, NULL) < 0) {
      fprintf(stderr, "Could not open codec\n");
      return 1;
  }
  return 0;
}

This prints "Could not open codec" because the raw video codec requires width/height/... information to be set. Which makes sense, but it took me a while to figure that out because it is in my opinion not documented clearly.

The only mention which comes close I found so far is in the decoding_encoding.c example where it says "For some codecs, such as msmpeg4 and mpeg4, width and height MUST be initialized there because this information is not available in the bitstream.." but there's no indication of how to do that exactly. The proper way to init everything for decoding seems to be to first open a file and find a stream, then use avcodec_find_decoder/avcodec_alloc_context3 and then use avcodec_parameters_to_context to copy the stream's codecpar info into the context before calling avcodec_open2. But that's just what I deduced from trying out different things to get raw video to decode, and I'm not even sure if my conclusion is correct.

So my point is: calling avcodec_alloc_context3 followed by avcodec_open2 immediately (as shown in multiple places in documentation and code samples) fails for some codecs unless certain parameters are already set in the context, but I could not find anything documenting that clearly. Yet it seems to be crucial in writing code which works for opening arbitrary video files.

Just mentioning this in the avcodec_open2 documentation would and updating samples accordingly would be great. I wouldn't mind contributing this, but then I'd need to now for sure if my assumption about avcodec_parameters_to_context being required before calling avcodec_open2 is correct.

comment:4 Changed 2 years ago by veroorzaker

  • Resolution needs_more_info deleted
  • Status changed from closed to reopened

comment:5 Changed 2 years ago by cehoyos

  • Component changed from undetermined to documentation
  • Priority changed from normal to minor

comment:6 Changed 22 months ago by chwinter

Thank you Veroorzaker, your findings helped me! I'd appreciate if someone with good knowledge of FFmpeg would approve that the conclusion of Veroorzaker is generally valid.

Note: See TracTickets for help on using tickets.