[Libav-user] Converting mpg file to ARGB frames

Drabner drabner at zoobe.com
Tue Oct 11 15:05:40 CEST 2011


Hey,

I am trying to decode an *.mpg video file into single frames and then
convert these frames to the ARGB format to pass them on to a DirectX-Shader
(to play them on an object).

Now my problem is that the decoding seems to work fine, but the conversion
to ARGB seems to really f*ck up. When outputting the frames, all I get is a
screwed up pixel mash and definitely not the video I encoded. And then it
crashes in the following memcpy function at some frame.

I am passing the converted frame to the texture like this (GetFrames()
returns a vector of previously created AVFrames, 640*360 is the texture and
video size):
*//-----------------------------------------------------------------*
/memcpy(textureDest, 
		_videoFrames->GetFrames()[_videoFramesPassed]->data, 
		4*640*360);/
*//-----------------------------------------------------------------*
The data-to-texture-to-shader-code itself works well, I tested it with some
random colors using D3DCOLOR_ARGB().

I decode the video like this:
*//-----------------------------------------------------------------*
/void 
FramesCollection::DecodeVideo(const char* p_filename)
{
	av_log(NULL, AV_LOG_ERROR, "%s","Starting video decoding\n");

	// Get the format context...
	int ret = avformat_open_input(&_videoFormatContext, p_filename, NULL,
NULL);
	if (ret < 0)
	{
		av_log(NULL, AV_LOG_ERROR, "%s","Error opening file '%s'\n", p_filename);
		exit(-1);
	}
	// ... and fill it with stream info (contains number of frames, etc.)
	av_find_stream_info(_videoFormatContext);

	// Find the video stream
	AVStream* stream;
	for(int i = 0; i < (int)_videoFormatContext->nb_streams; i++)
	{
		if(_videoFormatContext->streams[i]->codec->codec_type ==
AVMEDIA_TYPE_VIDEO) 
		{
			stream = _videoFormatContext->streams[i];
			break;
		}
	}

	// Use stream to set the context
	_videoCodecContext = stream->codec;

	// Find the codec
	_videoCodec = avcodec_find_decoder(_videoCodecContext->codec_id);
    if (!_videoCodec) 
	{
        av_log(_videoCodecContext, AV_LOG_ERROR, "%s","codec not found\n");
        exit(-1);
    }
	// Open the codec
	if (avcodec_open(_videoCodecContext, _videoCodec) < 0) 
	{
        av_log(_videoCodecContext, AV_LOG_ERROR, "%s","could not open
codec\n");
        exit(-1);
    }

	// Read each frame into a packet
	AVFrame *frame;
	frame = avcodec_alloc_frame();
	bool codexInitialized = false;
	SwsContext *converterContext = NULL;
	AVPacket packet;
	av_init_packet(&packet);
	while (av_read_frame(_videoFormatContext, &packet) == 0) 
	{
		// Decode the packet to get this frame
		int got_picture;
		int length;
		length = avcodec_decode_video2(_videoCodecContext, frame, &got_picture,
&packet);
		if (length < 0) 
		{
			av_log(_videoCodecContext, AV_LOG_ERROR, "%s","Error while decoding\n");
			exit(-1);
		}

		if (got_picture)
		{
			// Convert the image from its native format to ARGB (for shader)
			// Create correct context
			if (!codexInitialized)
			{
				converterContext = 
					sws_getContext(	_videoCodecContext->width, _videoCodecContext->height,
									_videoCodecContext->pix_fmt,
									_videoCodecContext->width, _videoCodecContext->height,
									PIX_FMT_ARGB, SWS_BICUBIC,
									NULL, NULL, NULL );
			}
			// Convert frame to target format
			AVFrame* dstFrame;
			dstFrame = avcodec_alloc_frame();
			avcodec_get_frame_defaults(dstFrame);
			avpicture_alloc((AVPicture*)dstFrame, PIX_FMT_ARGB, 
							_videoCodecContext->width, _videoCodecContext->height);	

			sws_scale(	converterContext, 
						frame->data, frame->linesize, 0, _videoCodecContext->height,
						dstFrame->data, dstFrame->linesize);

			// Save the frame
			_videoFrames.push_back(dstFrame);
		}
	} // END decoding each frame

	// Clean up
	av_free_packet(&packet);
	av_free(frame);
	if (converterContext)
		sws_freeContext(converterContext);
	if (_videoCodecContext)
		avcodec_close(_videoCodecContext);
	if (_videoFormatContext)
		av_close_input_file(_videoFormatContext);
}/
*//-----------------------------------------------------------------*

While decoding, I get the following message each frame (don't mind the log
format, it's my own):
*//-----------------------------------------------------------------*
/swscaler ********************
lvl: 24
msg: No accelerated colorspace conversion found from yuv420p to argb./
*//-----------------------------------------------------------------*

I don't think this causes the erratic behaviour, though.

Any ideas? Cause I certainly don't have any. HELP :(
Also, if anyone knows a video format in which this would definitely work,
I'd be glad to hear it, since I can use any video format for this, anyway.

--
View this message in context: http://libav-users.943685.n4.nabble.com/Converting-mpg-file-to-ARGB-frames-tp3894271p3894271.html
Sent from the libav-users mailing list archive at Nabble.com.


More information about the Libav-user mailing list