[Libav-user] Decode TS packets read from a queue

Danny Wilson danny at klarity.tv
Tue Nov 29 04:58:40 EET 2016


I need to decode MPEG-TS packets read from a queue.  Some posts on the internet suggest I can use AVFormatContext in conjunction with av_read_frame() to do this but I can't find any detailed documentation or examples.

The sample code below very simply simulates reading from the queue, but when processing an MPEG-TS containing *only* video packets, avcodec_decode_video2() returns "Invalid Data" and prints "no frame!"

Any suggestions on how to set up AVFormatContext to do this?  Or is there another, more simple, way to achieve this?

Thanks,
Danny

class VideoDecoder
{
public:
	VideoDecoder();
	bool rcvTsPacket(AVPacket &inTsPacket);

private:
	AVCodec         *mpDecoder;
	AVCodecContext  *mpDecoderContext;
	AVFrame         *mpDecodedFrame;
	AVFormatContext *mpFmtContext;

};

VideoDecoder::VideoDecoder()
{
	av_register_all();

	// FORMAT CONTEXT SETUP
	mpFmtContext = avformat_alloc_context();
	mpFmtContext->flags = AVFMT_NOFILE;
	// ????? WHAT ELSE ???? //

	// DECODER SETUP
	mpDecoder = avcodec_find_decoder(AV_CODEC_ID_H264);
	if (!mpDecoder)
	{
		printf("Could not load decoder\n");
		exit(11);
	}

	mpDecoderContext = avcodec_alloc_context3(NULL);
	if (avcodec_open2(mpDecoderContext, mpDecoder, NULL) < 0)
	{
		printf("Cannot open decoder context\n");
		exit(1);
	}

	mpDecodedFrame = av_frame_alloc();
}

bool
VideoDecoder::rcvTsPacket(AVPacket &inTsPkt)
{
	bool ret = true;

	if ((av_read_frame(mpFmtContext, &inTsPkt)) < 0)
	{
		printf("Error in av_read_frame()\n");
		ret = false;
	}
	else
	{
		// success.  Decode the TS packet
		int got;
		int len = avcodec_decode_video2(mpDecoderContext, mpDecodedFrame, &got, &inTsPkt);
		if (len < 0)
			ret = false;

		if (got)
			printf("GOT A DECODED FRAME\n");
	}
	return ret;
}

int
main(int argc, char **argv)
{
	FILE *tsInFile = fopen(argv[1], "r");

	unsigned int tsPktNum = 0;
	uint8_t      tsBuffer[256];
	AVPacket     tsPkt;
	av_init_packet(&tsPkt);

	VideoDecoder vDecoder;

	while (!feof(tsInFile))
	{
		tsPktNum++;

		tsPkt.size = 188;
		tsPkt.data = tsBuffer;
		fread(tsPkt.data, 188, 1, tsInFile);

		vDecoder.rcvTsPacket(tsPkt);
	}
}



More information about the Libav-user mailing list