Help with encoding and understanding avcodec_encode_video2

For the developers that use FFmpeg in their software.
Post Reply
ffpmegguy
Posts: 2
Joined: Mon Jun 25, 2012 11:30 am

Help with encoding and understanding avcodec_encode_video2

Post by ffpmegguy » Mon Jun 25, 2012 11:39 am

Hello, I recently started working with ffmpeg libraries and I'm kind of stuck. Basiclly my code opens a .FLV file. Decodes packets into frames. Then its supposed to encode it to .MP4(H264). Everything seems to run fine up to the encoding, first of I dont get a complete packet until after around 14 frames, is that normal? Then I have the following errors/warnings.

non strictly monotonic PTS

specified frame type is not compatible with max B-frames

specified frame type (5) at 11 is not compatible with the keyframe interval


Other than that if I change the width and height of my encoder, i get an error that the input is bigger than the stride?

Here is my code

Code: Select all

 ppAVO = av_guess_format("mp4", NULL, NULL);  //create an output format (MP4)
	
  int po = avformat_alloc_output_context2(&pFD, ppAVO, NULL, "c://wav//testme.mp4"); //create output context
	av_init_packet(&packet);
	 av_init_packet(&spacket);
  	pFC = avformat_alloc_context();
	pFD = avformat_alloc_context();
  avformat_open_input(&pFC, "c://wav//test2.flv", NULL, NULL);
	po = av_find_stream_info(pFC);
  // pRead = pFC->streams
	int jje = pFC->nb_streams;
	//ADD LOGIC TO FIND VIDEO STREAM
	pCodecC = pFC->streams[0]->codec;

	decoder = avcodec_find_decoder(pCodecC->codec_id);
	encoder = avcodec_find_encoder(pCodecC->codec_id);
	po = avcodec_open(pCodecC, decoder);
	pCodecE =  avcodec_alloc_context3(encoder);
	     /* put sample parameters */
   pCodecE->bit_rate = pCodecE->width * pCodecE->height * 4;//400000;
     /* resolution must be a multiple of two */
     pCodecE->width = 352;
    pCodecE->height = 288;
     /* frames per second */
	pCodecE->time_base.den = 30;//25
	pCodecE->time_base.num = 1;//1
   pCodecE->gop_size = 12;//10; /* emit one intra frame every ten frames */
   pCodecE->max_b_frames=0;//1;
   pCodecE->pix_fmt = PIX_FMT_YUV420P;

     if(pCodecC->codec_id == CODEC_ID_H264)
        av_opt_set(pCodecE->priv_data, "preset", "slow", 0);
	
	po =  avcodec_open2(pCodecE, encoder, NULL);

	AVFrame *pFrame;
	// Allocate an AVFrame structure
	


	// Allocate video frame
	pFrame=avcodec_alloc_frame();
	FILE * ff = fopen(filename,"r+");
	int frameFinished = 0;


AVFrame * pFrameRGB= avcodec_alloc_frame();

uint8_t *buffer;
int numBytes;
// Determine required buffer size and allocate buffer
numBytes=avpicture_get_size(PIX_FMT_RGB24, pCodecC->width,
                            pCodecC->height);
buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t));

// Assign appropriate parts of buffer to image planes in pFrameRGB
// Note that pFrameRGB is an AVFrame, but AVFrame is a superset
// of AVPicture
avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24,
                pCodecC->width, pCodecC->height);
int frame = 0;
	while(av_read_frame(pFC, &packet) >= 0)
   {
		if(packet.stream_index==0) //the video stream is 0
		{
		int len = avcodec_decode_video2(pCodecC, pFrame, &frameFinished, &packet);
			if(frameFinished)
			   {
				 printf("frame # %i", frame);
				 int gotpacket = 0;
					po	 =avcodec_encode_video2(pCodecE, &spacket, pFrame, &gotpacket);
				if(gotpacket)
				{
					printf("packet # %i", frame);
				}
				frameFinished = 0;
				gotpacket = 0;
				frame++;
				len = 0;
			}
		}
		av_free_packet(&packet);
		av_free_packet(&spacket);
	}


   printf("encoding done");
Any helping understanding the frame issue and the warnings would make me outmost grateful. Thanks in advance!

rogerdpack
Posts: 1877
Joined: Fri Aug 05, 2011 9:56 pm

Re: Help with encoding and understanding avcodec_encode_vide

Post by rogerdpack » Mon Jun 25, 2012 1:00 pm

What do you mean "don't get a complete packet"?
Since you've got it compiling, I would probably ask the libav users, etc. about the other weirdness.

Do you get those same error messages when using ffmpeg.exe to convert it?
-roger-

ffpmegguy
Posts: 2
Joined: Mon Jun 25, 2012 11:30 am

Re: Help with encoding and understanding avcodec_encode_vide

Post by ffpmegguy » Mon Jun 25, 2012 3:34 pm

Hi, what I mean is that gotPacket is set to 0, which means empty. Until about the 14th frame or so. After that, each frame returns a packet. Im new to this so I was just wondering if that can happen or there is some error in my code. Maybe the frames are empty? I don't know.

Also on top of my previous post, I tried adding functionality for writing the frames to a container. To see if it was working. Though i get a 'divided by zero' error when trying to write the frames to the container on disk. Here is the code.

Code: Select all

	av_init_packet(&packet);
	 av_init_packet(&spacket);
  	pFC = avformat_alloc_context();
	pFD = avformat_alloc_context();
	int po = 0;
  avformat_open_input(&pFC, "c://wav//test2.flv", NULL, NULL);
	po = av_find_stream_info(pFC);
  // pRead = pFC->streams
	int jje = pFC->nb_streams;
	//ADD LOGIC TO FIND VIDEO STREAM
	pCodecC = pFC->streams[0]->codec;

	decoder = avcodec_find_decoder(pCodecC->codec_id);
	encoder = avcodec_find_encoder(pCodecC->codec_id);
	po = avcodec_open(pCodecC, decoder);
	pCodecE =  avcodec_alloc_context3(encoder);
	     /* put sample parameters */
   pCodecE->bit_rate = pCodecE->width * pCodecE->height * 4;//400000;
     /* resolution must be a multiple of two */
     pCodecE->width = 352;
    pCodecE->height = 288;
     /* frames per second */
	pCodecE->time_base.den = 30;//25
	pCodecE->time_base.num = 1;//1
   pCodecE->gop_size = 12;//10; /* emit one intra frame every ten frames */
   pCodecE->max_b_frames=2;//1;
   pCodecE->pix_fmt = PIX_FMT_YUV420P;

     if(pCodecC->codec_id == CODEC_ID_H264)
        av_opt_set(pCodecE->priv_data, "preset", "slow", 0);
	
	po =  avcodec_open2(pCodecE, encoder, NULL);

	AVStream *VideoStream = avformat_new_stream(pFD, encoder);


	po = avio_open(&pFD->pb, "c://wav//testme.mp4", AVIO_FLAG_READ_WRITE);
	//po = avformat_write_header(pFD, NULL);

	AVFrame *pFrame;
	// Allocate an AVFrame structure
	


	// Allocate video frame
	pFrame=avcodec_alloc_frame();
	FILE * ff = fopen(filename,"r+");
	int frameFinished = 0;


AVFrame * pFrameRGB= avcodec_alloc_frame();

uint8_t *buffer;
int numBytes;
// Determine required buffer size and allocate buffer
numBytes=avpicture_get_size(PIX_FMT_RGB24, pCodecC->width,
                            pCodecC->height);
buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t));

// Assign appropriate parts of buffer to image planes in pFrameRGB
// Note that pFrameRGB is an AVFrame, but AVFrame is a superset
// of AVPicture
avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24,
                pCodecC->width, pCodecC->height);
int frame = 0;
	while(av_read_frame(pFC, &packet) >= 0)
   {
		if(packet.stream_index==0) //the video stream is 0
		{
		int len = avcodec_decode_video2(pCodecC, pFrame, &frameFinished, &packet);
			if(frameFinished)
			   {
				 printf("frame # %i", frame);
				 int gotpacket = 0;
					po	 =avcodec_encode_video2(pCodecE, &spacket, pFrame, &gotpacket);
				if(gotpacket)
				{
					printf("packet # %i", frame);
					po = av_write_frame(pFD, &spacket);
				}
				frameFinished = 0;
				gotpacket = 0;
				frame++;
				len = 0;
			}
		}
		av_free_packet(&packet);
		av_free_packet(&spacket);
	}

po = av_write_frame(pFD, NULL);//flush the data
po = av_write_trailer(pFD);
   printf("encoding done");

	return 0;
the coded added is

Code: Select all

	AVStream *VideoStream = avformat_new_stream(pFD, encoder);

	po = avio_open(&pFD->pb, "c://wav//testme.mp4", AVIO_FLAG_READ_WRITE);
	po = avformat_write_header(pFD, NULL);

        po = av_write_frame(pFD, &spacket);

       po = av_write_frame(pFD, NULL);//flush the data
       po = av_write_trailer(pFD);

Code: Select all

po = avformat_write_header(pFD, NULL);
gives me the error, time base not set.

So I tried without it. Not sure if that plays any part of it. Eitherway,

Code: Select all

po = av_write_frame(pFD, &spacket);
fails with divided by zero.

So not sure what's wrong here :(

rogerdpack
Posts: 1877
Joined: Fri Aug 05, 2011 9:56 pm

Re: Help with encoding and understanding avcodec_encode_vide

Post by rogerdpack » Mon Jun 25, 2012 4:15 pm

I'd ask the libav-users group

Post Reply
'