[FFmpeg-user] Access Violation in avcodec_encode_video

Drabner drabner at zoobe.com
Fri Sep 23 13:19:18 CEST 2011


I am trying to write frames into an output file (mp4 container, codec is
h264).

This is the code that always gets an Access Violation:

/avcodec_encode_video(outputFormatContext->streams[0]->codec, outbuf,
outbufSize, frame);/

outbuf is correctly allocated with av_malloc(outbufSize) with outbufSize
being FF_MIN_BUFFER_SIZE.
But all sizes bigger than that also cause the same error.

frame is an AVFrame* that was filled by sws_scale, converting to
PIX_FMT_YUV420P.

The format context (and the codec context) is also correctly initialized and
opened with the correct codec.

Up to the point with the access violation crash, ffmpeg reports absolutely
no errors or warnings, so I guess I did everything correct.

Any ideas what could go wrong here?

Here is the complete code (_videoFrames is a vector filled with previously
decoded AVFrames, the alloc_picture function is at the bottom):

-------------------------------------------------------
-------------------------------------------------------
void 
FramesCollection::TestVideoEncode()
{
	av_log(NULL, AV_LOG_ERROR, "%s","Start video encoding.\n");

	// Try writing
	AVFormatContext* outputContext;
	outputContext = avformat_alloc_context();
	outputContext->oformat = 
		av_guess_format("mp4", NULL, NULL);//_videoFormatContext->filename, NULL);
	char buffer[512];
	sprintf(buffer, "C:\\zoobe\\outTest_video.%s",
outputContext->oformat->name);
	_snprintf_s(outputContext->filename, 
				sizeof(outputContext->filename), 
				strlen(buffer), 
				"%s", buffer);

	// Add stream
	if (!av_new_stream(outputContext, 0))
	{
		av_log(outputContext, AV_LOG_ERROR, "%s","Error while creating
stream.\n");
		exit(-1);
	}

	// Find Codec
	AVCodec* outCodec = avcodec_find_decoder(CODEC_ID_H264);
    if (!outCodec) 
	{
        av_log(outputContext, AV_LOG_ERROR, "%s","codec not found\n");
        exit(-1);
    }
	// Open Codec
	if (avcodec_open(outputContext->streams[0]->codec, outCodec) < 0)
	{
		av_log(outputContext->streams[0]->codec, AV_LOG_ERROR, "%s","Error while
opening codec for context.\n");
		exit(-1);
	}
	// Open Codec
	/*if (avcodec_open(outputContext->streams[0]->codec, _videoCodec) < 0)
	{
		av_log(outputContext->streams[0]->codec, AV_LOG_ERROR, "%s","Error while
opening codec for context.\n");
		exit(-1);
	}*/

	// Set time base, dimensions, etc.
	outputContext->streams[0]->codec->time_base =
_videoCodecContext->time_base;
	outputContext->streams[0]->codec->width = _videoCodecContext->width;
	outputContext->streams[0]->codec->height = _videoCodecContext->height;
	// Some container formats want stream headers to be global
	if(outputContext->oformat->flags & AVFMT_GLOBALHEADER)
	{
		outputContext->streams[0]->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
	}

	// Open output file
	if (url_fopen(&outputContext->pb, outputContext->filename, URL_WRONLY) < 0) 
	{
		av_log(outputContext, 
				AV_LOG_ERROR, "%s","Could not open '%s'\n", outputContext->filename);
		exit(-1);
	}

	// Write Header
	if (avformat_write_header(outputContext, NULL) < 0)
	{
		av_log(outputContext, AV_LOG_ERROR, "%s","Error while writing header.\n");
		exit(-1);
	}

	// Write each frame
	int outbufSize = FF_MIN_BUFFER_SIZE;
	uint8_t* outbuf = new uint8_t[outbufSize];
	for (int i = 0; i < (int)_videoFrames.size(); i++)
	{
		// Convert the frame to correct format
		SwsContext* convertContext = 
			sws_getContext(	_videoFrames[i]->width, _videoFrames[i]->height,
							_videoCodecContext->pix_fmt,
							_videoFrames[i]->width, _videoFrames[i]->height,
							PIX_FMT_YUV420P,
							SWS_BICUBIC, NULL, NULL, NULL );
		if (!convertContext) 
		{
			av_log(outputContext->streams[0]->codec, AV_LOG_ERROR, "%s","Cannot
initialize the conversion context\n");
			exit(1);
		}
		AVFrame *frame;
		frame = alloc_picture(PIX_FMT_YUV420P, _videoFrames[i]->width,
_videoFrames[i]->height);
		int outSize = sws_scale(convertContext,
								_videoFrames[i]->data, _videoFrames[i]->linesize,
								0, _videoFrames[i]->height,
								frame->data, frame->linesize);
		if (outSize <= 0)
		{
			av_log(outputContext, AV_LOG_ERROR, "%s","Error while scaling frame.\n");
			exit(-1);
		}

		// Encode the frame
		av_log(outputContext, AV_LOG_ERROR, "%s %i \n","Writing frame:",i);
		outSize = avcodec_encode_video(	outputContext->streams[0]->codec,
										outbuf, outbufSize, frame);
		if (outSize < 0)
		{
			av_log(outputContext, AV_LOG_ERROR, "%s","Error while encoding
frame.\n");
			exit(-1);
		}
		else if (outSize > 0)
		{
			// Write the frame
			AVPacket pkt;
			av_init_packet(&pkt);
			if (outputContext->streams[0]->codec->coded_frame->pts != AV_NOPTS_VALUE)
			{
				pkt.pts =
av_rescale_q(outputContext->streams[0]->codec->coded_frame->pts,
										outputContext->streams[0]->codec->time_base, 
										outputContext->streams[0]->time_base);
			}
			if(outputContext->streams[0]->codec->coded_frame->key_frame)
				pkt.flags |= AV_PKT_FLAG_KEY;

			pkt.stream_index = outputContext->streams[0]->index;
			pkt.data = outbuf;
			pkt.size = outSize;

			int ret = av_write_frame(outputContext, &pkt); 
			if (ret < 0)
			{
				av_log(outputContext, AV_LOG_ERROR, "%s","Error while writing
frame.\n");
				exit(-1);
			}
		}
	}

	// Write trailer
	if (av_write_trailer(outputContext) < 0)
	{
		av_log(outputContext, AV_LOG_ERROR, "%s","Error while writing
trailer.\n");
		exit(-1);
	}

	// Close stuff
	avcodec_close(outputContext->streams[0]->codec);
	url_fclose(outputContext->pb);
	avformat_free_context(outputContext);
}

-------------------------------------------------------
-------------------------------------------------------
AVFrame *alloc_picture(enum PixelFormat pix_fmt, int width, int height )
{
	AVFrame *picture;
	uint8_t *picture_buf;
	int size;

	picture = avcodec_alloc_frame();
	if (!picture)
		return NULL;
	size = avpicture_get_size(pix_fmt, width, height);
	picture_buf = (uint8_t *) av_malloc(size);
	if (!picture_buf) {
		av_free(picture);
		return NULL;
	}
	avpicture_fill((AVPicture *)picture, picture_buf,
		pix_fmt, width, height);
	return picture;
}


--
View this message in context: http://ffmpeg-users.933282.n4.nabble.com/Access-Violation-in-avcodec-encode-video-tp3836503p3836503.html
Sent from the FFmpeg-users mailing list archive at Nabble.com.


More information about the ffmpeg-user mailing list