bytedeco/javacv

Failure to use avcodec_send_frame

Open

#1,238 opened on Jun 26, 2019

View on GitHub
 (9 comments) (0 reactions) (0 assignees)Java (1,583 forks)batch import
enhancementhelp wantedquestion

Repository metrics

Stars
 (6,985 stars)
PR merge metrics
 (No merged PRs in 30d)

Description

Hello,

My goal is to encode a sequence of raw frames into a h.264 stream.

I am using the avcodec_send_frame but it fails with the "Invalid argument" error message:

if ((avrc = avcodec.avcodec_send_frame(codecContext, frame)) < 0) {
  avutil.av_strerror(avrc, avErrorDescription, avErrorDescription.length);
  String error = new String(avErrorDescription); //TODO: remove, debug item
  LOGGER.error("Could not add frame to encoding pipeline, error code {}, exiting", avrc);
  return;
}

Before the avcodec_send_frame call I do (left out return codes verifications):

AVCodecContext codecContext = new avcodec.AVCodecContext(null);
avutil.AVFrame frame = new avutil.AVFrame(null);
avcodec.AVPacket avPacket = new avcodec.AVPacket(null);

avcodec.avcodec_register_all();
AVCodec h264Codec = avcodec.avcodec_find_decoder_by_name("h264");
codecContext = avcodec.avcodec_alloc_context3(h264Codec);
avPacket = avcodec.av_packet_alloc();
codecContext.bit_rate(1000000);
codecContext.width(704);
codecContext.height(480);
avutil.AVRational timeBase = new avutil.AVRational();
timeBase.num(1);
timeBase.den(25);
codecContext.time_base(timeBase);
avutil.AVRational frameRate = new avutil.AVRational();
frameRate.num(25);
frameRate.den(1);
codecContext.framerate(frameRate);
codecContext.gop_size(25);
codecContext.max_b_frames(10);
codecContext.pix_fmt(AV_PIX_FMT_YUV420P);
if (codecContext.codec_id() == AV_CODEC_ID_H264) {
  avutil.av_opt_set(codecContext, "preset", "slow", 0);
}
avutil.AVDictionary dictionary = null;
avcodec_open2(codecContext, h264Codec, dictionary);
frame = av_frame_alloc();
frame.format(codecContext.pix_fmt());
frame.width(codecContext.width());
frame.height(codecContext.height());
av_frame_get_buffer(frame, 0);
av_frame_make_writable(frame);
org.bytedeco.javacpp.BytePointer rawData = new org.bytedeco.javacpp.BytePointer(data.getData().getByteBuffer(0, data.getData().getSize())); //data is the raw frame to be encoded
frame.data(0, rawData);
frame.linesize(0, width);
av_image_fill_pointers(frame.data(), codecContext.pix_fmt(), codecContext.height(), rawData, frame.linesize());
avcodec.avcodec_send_frame(codecContext, frame); // Fails with rc = -22 (Invalid argument)

Is the sequence incorrect? What am I missing?

Thanks!

Raul

Contributor guide