Start a new topic

How should I decode with libav the packets obtained through the v4l2 api in mmap mode?

I'm trying to write an application to transcode and resend the h264 feed of a BC-H08480 and I have some trouble decoding the packets I get via the video4linux API while using the MMAP I/O mode, obtaining them like it's done in "bc-record.c".

The thing is, I'm successfully getting the packets from the V4L2 device, 30 per second (so I assume there's one packet per frame). But when I build an AVPacket out of it and handle it over to avcodec_decode_video2, it does only give me an output frame every now and then (In fact, I've observed I'm only obtaining a frame when the v4l2 buffer has a packet flagged with V4L2_BUF_FLAG_KEYFRAME).

So I'm obviously doing something wrong here.

Is there someone who could enlighten me a bit, please? I'm completely stuck :-/


P.S. The code inside my decoding loop looks similar to this:

  1. v4l2buff.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

  2. v4l2buff.memory = V4L2_IO_METHOD_MMAP;

  3. if ((ret = xioctl(v4l2_fd, VIDIOC_DQBUF, &v4l2buff)) == -1) handle_error();

  4. av_init_packet(&packet); // Init the packet

  5. = (uint8_t *)buffers[v4l2buff.index].start;

  6. packet.size = v4l2buff.bytesused;

  7. packet.flags |= (v4l2buff.flags & V4L2_BUF_FLAG_KEYFRAME)?1:0;

  8. ret = avcodec_decode_video2(codec_ctx, frame, &got_pic, &packet);

  9. if ((ret >= 0) && got_pic) {

  10. printf("Got a full decoded frame!\n");

  11. }

  12. if ((ret = xioctl(v4l2_fd, VIDIOC_QBUF, &v4l2buff)) == -1) handle_error();

Previously I initialized the codec context by calling avcodec_alloc_context3() and passing it a codec pointer obtained with avcodec_find_decoder(AV_CODEC_ID_H264). I'm not sure if I'm missing something important here.

I also had to set up the flag CODEC_FLAG2_CHUNKS in the flags2 member of the context to prevent the decoder from throwing me a "no frame" error for every packet I send to it.

Oh, and I set up the time_base of the context to 1/30.

What else could I be missing?

Login or Signup to post a comment