[FFmpeg-user] Segmentation Faults - avcodec_encode_video Please Help

Aditya adi235 at gmail.com
Mon May 9 14:01:51 CEST 2011


I am writing a simple C program to accept video input decode it encode it into
flv and then save output video file. I have looked at danger's tutorials,
output-example.c,api-example.c and such. But i seem to be missing something very
essential. And always end up encountering , segmentation faults, ( sometimes
buffer under flows or warning max analysis time reached.  The below is the
program. I would very much appreciate for a clear solution to this problem. I
have spend to many days trying to figure this out already.

[CODE]
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

static void SaveFrame(AVFrame *pFrame, int width, int height, int iFrame);
AVFormatContext *pFormatCtx;
static int i, videoStream;
AVCodecContext *pCodecCtx;
AVCodec *pCodec;
AVFrame *pFrame;
AVFrame *pFrameRGB;
AVPacket packet;
static int frameFinished;
static int numBytes;
static uint8_t *buffer;
AVCodec *codec;
AVCodecContext *c = NULL;
int out_size, size, outbuf_size;
uint8_t *outbuf;
FILE *f;

int init_video_file(char *inputFileName) {
	// Register all formats and codecs
	av_register_all();

	// Open video file
	if (av_open_input_file(&pFormatCtx, inputFileName, NULL, 0, NULL) != 0)
		return -1; // Couldn't open file

	// Retrieve stream information
	if (av_find_stream_info(pFormatCtx) < 0)
		return -1; // Couldn't find stream information

	// Dump information about file onto standard error
	dump_format(pFormatCtx, 0, inputFileName, false);

	// Find the first video stream
	videoStream = -1;
	for (i = 0; i < pFormatCtx->nb_streams; i++)
		if (pFormatCtx->streams[i]->codec->codec_type == CODEC_TYPE_VIDEO) {
			videoStream = i;
			break;
		}
	if (videoStream == -1)
		return -1; // Didn't find a video stream

	return 0;
}
int init_video_codec() {

	// Get a pointer to the codec context for the video stream
	pCodecCtx = pFormatCtx->streams[videoStream]->codec;

	// Find the decoder for the video stream
	pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
	if (pCodec == NULL)
		return -1; // Codec not found

	// Open codec
	if (avcodec_open(pCodecCtx, pCodec) < 0)
		return -1; // Could not open codec

	return 0;
}
int set_frame_data() {
	// Hack to correct wrong frame rates that seem to be generated by some codecs
	if (pCodecCtx->time_base.num > 1000 && pCodecCtx->time_base.den == 1)
		pCodecCtx->time_base.den = 1000;

	// Allocate video frame
	pFrame = avcodec_alloc_frame();

	// Allocate an AVFrame structure
	pFrameRGB = avcodec_alloc_frame();
	if (pFrameRGB == NULL)
		return -1;

	// Determine required buffer size and allocate buffer
	numBytes = avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width,
			pCodecCtx->height);

	buffer = malloc(numBytes);

	// Assign appropriate parts of buffer to image planes in pFrameRGB
	avpicture_fill((AVPicture *) pFrameRGB, buffer, PIX_FMT_RGB24,
			pCodecCtx->width, pCodecCtx->height);

	return 0;
}

void process_packet_data(char *outFileName) {
	// Read frames and save first five frames to disk
	i = 0;
	while (av_read_frame(pFormatCtx, &packet) >= 0) {
		// Is this a packet from the video stream?
		if (packet.stream_index == videoStream) {
			// Decode video frame
			avcodec_decode_video(pCodecCtx, pFrame, &frameFinished,
					packet.data, packet.size);

			// Did we get a video frame?
			if (frameFinished) {
				//printf("\n packet size= %d \t  pframe number=n%d ", packet.size,
					//	pFrame->coded_picture_number);
                     
				 // Insane segmentation faults when encoding the got frame.. !!Help.
				//out_size = avcodec_encode_video(c, outbuf, outbuf_size, pFrame);

				save_frame_as_image();

			}
		}

		// Free the packet that was allocated by av_read_frame
		av_free_packet(&packet);
	}

}

void set_encoder_for_output(const char *filename) {

	uint8_t *outbuf;

	printf("Video encoding\n");

	/* find the mpeg1 video encoder */
	codec = avcodec_find_encoder(CODEC_ID_FLASHSV);
	if (!codec) {
		fprintf(stderr, "codec not found\n");
		exit(1);
	}

	c = avcodec_alloc_context();
	pFrame = avcodec_alloc_frame();

	/* put sample parameters */
	c->bit_rate = 128000;
	/* resolution must be a multiple of two */
	c->width = 320;
	c->height = 240;
	/* frames per second */
	c->time_base = (AVRational) {1,25};
			c->gop_size = 10; /* emit one intra frame every ten frames */
			c->max_b_frames=1;
			c->pix_fmt = PIX_FMT_YUV420P;

			/* open it */
			if (avcodec_open(c, codec) < 0) {
				fprintf(stderr, "could not open codec\n");
				exit(1);
			}

			f = fopen(filename, "wb");
			if (!f) {
				fprintf(stderr, "could not open ______::: %s\n", filename);
				exit(1);
			}

			/* alloc image and output buffer */
			outbuf_size = 230400;
			outbuf = malloc(outbuf_size);
			size = c->width * c->height;

			//out_size = avcodec_encode_video(c, outbuf, outbuf_size, picture);
		}
void cleanup() {
	// Free the RGB image'

	free(outbuf);
	avcodec_close(c);
	av_free(c);
	printf("\n");

	free(buffer);
	av_free(pFrameRGB);

	// Free the YUV frame
	av_free(pFrame);

	// Close the codec
	avcodec_close(pCodecCtx);

	// Close the video file
	av_close_input_file(pFormatCtx);

}
void encode_frames_to_video() {

}
void save_frame_as_image() {
	static struct SwsContext *img_convert_ctx;

	 // Convert the image into YUV format that SDL uses
	 if (img_convert_ctx == NULL) {
	 int w = pCodecCtx->width;
	 int h = pCodecCtx->height;

	 img_convert_ctx = sws_getContext(w, h, pCodecCtx->pix_fmt, w, h,
	 PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL);

	 if (img_convert_ctx == NULL) {
	 fprintf(stderr, "Cannot initialize the conversion context!\n");
	 exit(1);
	 }
	 }
	 int ret = sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0,
	 pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);

	 // Save the frame to disk
	 if (i++ <= 5)
	 SaveFrame(pFrameRGB, pCodecCtx->width, pCodecCtx->height, i);

}
int main(int argc, char * argv[]) {

	init_video_file(argv[1]);
	init_video_codec();
	set_frame_data();
	set_encoder_for_output(argv[2]);
	process_packet_data(argv[2]);
	cleanup();
	return 0;
}

static void SaveFrame(AVFrame *pFrame, int width, int height, int iFrame) {
	FILE *pFile;
	char szFilename[32];
	int y;

	// Open file
	sprintf(szFilename, "frame%d.ppm", iFrame);
	pFile = fopen(szFilename, "wb");
	if (pFile == NULL)
		return;

	// Write header
	fprintf(pFile, "P6\n%d %d\n255\n", width, height);

	// Write pixel data
	for (y = 0; y < height; y++)
		fwrite(pFrame->data[0] + y * pFrame->linesize[0], 1, width * 3, pFile);

	// Close file
	fclose(pFile);
}
[/CODE]

[b] Kindly help in resolving the segmentation faults in the above program [/b]

I have been unable to find any straight forward example on how to do this. 

Thanks



More information about the ffmpeg-user mailing list