[Libav-user] Decoding Problem (got_picture always return 0)

吴沁凡 wuqinfan at gmail.com
Fri Mar 23 01:39:29 CET 2012


The incoming data received by the client can be an incomplete frame (or may
be more than one frame, since the data is not organized as the same as you
wrote at server end), so you can not decode it directly.
Use function av_parser_parse2() first to get complete frame one by one from
the incoming data.

for usage of av_parse_parse2(), please refer to avcodec.h
Here is my code for decoding. I also tried a lot, since the examples in
ffmpeg only tell about decode complete frames.

void Server::process()
{
	QTcpSocket *socket = nextPendingConnection();
	cout << "client connected." << endl;

	uint8_t *inbuf = new uint8_t [20000000];
	int inbuf_start = 0;
	int inbuf_len = 0;

	while (socket->waitForReadyRead())
	{
		QByteArray ba = socket->readAll();
		if (ba.size() == 0)
		{
			cerr << "read 0 bytes data." << endl;
			continue;
		}
		memcpy(inbuf + inbuf_len, ba.data(), ba.size());
		inbuf_len += ba.size();

		uint8_t *poutbuf;
		int poutbuf_size;
		while (inbuf_len)
		{
			int len = av_parser_parse2(parser, ctx, &poutbuf, &poutbuf_size,
					inbuf + inbuf_start, inbuf_len,
					AV_NOPTS_VALUE, AV_NOPTS_VALUE, 0);

			inbuf_start += len;
			inbuf_len -= len;

			if (poutbuf_size)
			{
				av_init_packet(&avpkt);
				avpkt.data = poutbuf;
				avpkt.size = poutbuf_size;

				int got_picture;
				int retval = avcodec_decode_video2(ctx, frame, &got_picture, &avpkt);
				if (got_picture && retval > 0)
				{
					for (int i = 0; i < 480; i++)
						memcpy(img.data + i*640, frame->data[0] + i*frame->linesize[0], 640);

					emit rawDataReady();
				}
			}
			else // this group of data is less than a complete frame
			{
				if (inbuf_start > 0)
				{
					uint8_t *tmp = new uint8_t [20000000];
					memcpy(tmp, inbuf + inbuf_start, inbuf_len);
					memcpy(inbuf, tmp, inbuf_len);
					inbuf_start = 0;
					delete [] tmp;
				}

				break;
			}
		}
	}
}


2012/3/23 Yinxia <hydezhao at gmail.com>

> Hi dear all,
>
> I am a newbie to ffmpeg and I would like to decode the bitstream, which is
> encoded using libx264 at the server end and sent to client frame by frame.
>
> I wrote a function decodeFrame to decode this bitstream frame by frame,
> this function is called in a loop, each time recieves a new frame:
>
> void decodeFrame( int size, unsigned char *data)
> {
>  avpkt.size = size;
> avpkt.data = (uint8_t *)(data);
>
> /*decode each frame*/
>  len = avcodec_decode_video2(c, picture, &got_picture, avpkt.size);
> if (len < 0) {
>  fprintf(stderr, "[avcodec][Err] Error while decoding frame %d\n",frame);
>  exit(1);
> }
>  if (got_picture) {
> printf("[avcodec] Saving frame %3d\n",frame);
>  fflush(stdout);
> _snprintf(buf, sizeof(buf), "/temp/video%d.pgm", frame); // not found
>  pgmSave(picture->data[0], picture->linesize[0], c->width, c->height, buf);
>  frame++;
> }
> }
>
> I can successfully get the value of len, which is exactly the size of
> frame, however, *the value of *got_picture *is always 0. *Can anyone help
> me with this?
> *
> *
> PS. this is the init function of decoder.
>
> void initDecoder()
> {
> avcodec_register_all();
>
> av_init_packet(&avpkt);
> memset(inbuf + INBUF_SIZE, 0, FF_INPUT_BUFFER_PADDING_SIZE);
>  printf("[avcodec] Frame decoding initializing\n");
>
> /*choose correct video decoder*/
>  codec = avcodec_find_decoder(CODEC_ID_MPEG4);
> if ( !codec ) {
> fprintf(stderr, "[avcodec][Err] codec not found!\n");
>  exit(1);
> }
>
> c = avcodec_alloc_context3(codec);
>  picture = avcodec_alloc_frame();
>
> if(codec->capabilities&CODEC_CAP_TRUNCATED)
>           c->flags|= CODEC_FLAG_TRUNCATED; /* we do not send complete
> frames */
>
>    /* open it */
>    if (avcodec_open2(c, codec, NULL) < 0) {
>        fprintf(stderr, "[avcodec][Err] could not open codec\n");
>        exit(1);
>    }
>
>
> frame = 0;
>
> }
>
>
> Thank you very much!
> Yinxia
>
>
> --
> View this message in context:
> http://libav-users.943685.n4.nabble.com/Decoding-Problem-got-picture-always-return-0-tp4496039p4496039.html
> Sent from the libav-users mailing list archive at Nabble.com.
> _______________________________________________
> Libav-user mailing list
> Libav-user at ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/libav-user
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://ffmpeg.org/pipermail/libav-user/attachments/20120323/3440d9ef/attachment.html>


More information about the Libav-user mailing list