Click here to Skip to main content
15,905,508 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
Right now I'm trying to encode some Images to an mp4 file with the help of the libav headers. the Encoding was succesful, after the Encoding i receive some Output, and an mp4 file is generated. But somehow I can not Play the Video with normal Players. Am I missing something?

This is how i created the Output Container
C++
void create_video(char *filename)
{

    AVOutputFormat *fmt;
    AVCodecContext *codecctx;
    AVFormatContext *fmtctx;
    fmt=av_guess_format(NULL,filename,NULL);
    if(!fmt)
        printf("Das Format kann nicht erkannt werden. MPEG wird verwendet");
    AVCodec *codec = avcodec_find_encoder(fmt->video_codec);
    if(codec==NULL)
        printf("Codec nicht gefunden");
    codecctx = avcodec_alloc_context3(codec);
    codecctx->codec_id = fmt->video_codec;
    codecctx->codec_type = AVMEDIA_TYPE_VIDEO;
    codecctx->gop_size = 12;
    codecctx->bit_rate = 800*280*4;
    codecctx->width = 800;
    codecctx->height = 280;

    codecctx->time_base.den = 30; 
    codecctx->time_base.num =1;
    //codecctx->time_base =(AVRational){1,FPS};
    codecctx->max_b_frames=1;
    codecctx->pix_fmt= STREAM_PIX_FMT;
    fmtctx = avformat_alloc_context();
    fmtctx->oformat = fmt;
    fmtctx->video_codec_id = fmt->video_codec;

    avcodec_open2(codecctx, codec, NULL);
    if(avcodec_open2(codecctx, codec, NULL)<0)
        printf("Error opening the codec \n");
    AVStream *VideoStream = avformat_new_stream(fmtctx,0);
    VideoStream->codecpar->codec_id=fmt->video_codec;
    VideoStream->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
    VideoStream->codecpar->format = STREAM_PIX_FMT;
    VideoStream->codecpar->width=800;
    VideoStream->codecpar->height=280;
    VideoStream->time_base.den=30;
    VideoStream->time_base.num=1;
    VideoStream->codec=codecctx;

    avio_open(&fmtctx->pb,filename,AVIO_FLAG_WRITE);

    if(avformat_write_header(fmtctx,NULL)==0)
    {
        Write_Video_Frame(fmtctx,VideoStream,"1.png");
        Write_Video_Frame(fmtctx,VideoStream,"C:/Users/delemi/Desktop/Images/img002.png");
        Write_Video_Frame(fmtctx,VideoStream,"C:/Users/delemi/Desktop/Images/img003.png");
        Write_Video_Frame(fmtctx,VideoStream,"C:/Users/delemi/Desktop/Images/img004.png");
        Write_Video_Frame(fmtctx,VideoStream,"C:/Users/delemi/Desktop/Images/img005.png");
        Write_Video_Frame(fmtctx,VideoStream,"C:/Users/delemi/Desktop/Images/img006.png");
        Write_Video_Frame(fmtctx,VideoStream,"C:/Users/delemi/Desktop/Images/img007.png");
        av_write_trailer(fmtctx);
    }
}


And the add Frame function:
C++
<pre lang="C++">static void Write_Video_Frame(AVFormatContext *oc, AVStream *st, char* datei)
{
    frame_count++;	
	double pts;
	int test, videoStream,frameFinished,x,y;
	AVFormatContext *pFormatCtx =avformat_alloc_context();
	int i;
	
	int size = WIDTH*HEIGHT;
	
	if (avformat_open_input(&pFormatCtx, datei, NULL, NULL) !=0)
		printf("Das Bild kann nicht geoeffnet werden!");
	test = avformat_find_stream_info(pFormatCtx, NULL);
	if(test<0)
		printf("Es konnte kein Stream von dem Bild gefunden werden. \n");
	
AVCodecContext *c = NULL;
AVCodecContext *pCodecCtx = NULL;
c=st->codec;

// Find the first video stream
videoStream=-1;
for(i=0; i<pFormatCtx->nb_streams; i++)
  if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO) {
    videoStream=i;
	
    break;
  }
// Get a pointer to the codec context for the video stream
pCodecCtx=pFormatCtx->streams[videoStream]->codec;
if(pCodecCtx == NULL)
	printf("CodecCtx not found");
AVCodec *pCodec = NULL;

// Find the decoder for the video stream

pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
if(pCodec==NULL) {
  fprintf(stderr, "Unsupported codec of the picture \n");
  }
// Oeffnet den Codec
if(avcodec_open2(pCodecCtx, pCodec,NULL)<0)
	fprintf(stderr,"Error opening the codec of the picture \n");
AVFrame *pFrame;
AVFrame *pFrameYUV;
pFrame = av_frame_alloc();
pFrameYUV = av_frame_alloc();
int numBytes;
uint8_t *buffer= NULL;
numBytes=avpicture_get_size(AV_PIX_FMT_YUV420P, pCodecCtx->width,pCodecCtx->height); 
buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t)); 
uint8_t *picture_buf = (uint8_t *)av_malloc(numBytes*sizeof(uint8_t));


struct SwsContext *sws_ctx = NULL;
av_image_alloc(    pFrameYUV->data,   //data to be filled
                   pFrameYUV->linesize,//line sizes to be filled
                   800, 280,
                   AV_PIX_FMT_YUV420P,           //pixel format
                   32                       //alingn
                   );
sws_ctx = sws_getContext(800,280,AV_PIX_FMT_RGB24,800,280,AV_PIX_FMT_YUV420P,SWS_BICUBIC,0,0,0);
if(sws_ctx==NULL)
	printf("Error");
AVPacket packet;
int zahl =0;
// initialize SWS context for software scaling
pFrameYUV->height = pFrame->height = pCodecCtx->height;
pFrameYUV->width = pFrame->width = pCodecCtx->width;
pFrameYUV->format = AV_PIX_FMT_YUV420P;
 fflush(stdout);
while (av_read_frame(pFormatCtx,&packet)>=0)
{
	if(packet.stream_index == videoStream)
	{
		avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet); 
		
		if(frameFinished)
		{
			zahl++;
			sws_scale(sws_ctx,pFrame->data,pFrame->linesize,0,pCodecCtx->height,pFrameYUV->data,pFrameYUV->linesize);
			printf("Packet size : %d \n ",packet.size);
			
		}
	}
	av_free_packet(&packet);
}
printf("Total frames found: %d \n",zahl);
avcodec_close(pCodecCtx);
/*Find the encoder of the stream and open it*/
pCodec=avcodec_find_encoder(c->codec_id);
if(avcodec_find_encoder(c->codec_id)==NULL)
	printf("Could not find the codec of ouput");
if(avcodec_open2(c,pCodec,NULL)<0)
	printf("Error opening the codec of output");
AVPacket encoded;
int got_packet;
for(i=0;i<30;i++)
{
av_init_packet(&encoded);

encoded.data = NULL;    // packet data will be allocated by the encoder
encoded.size = 0;
fflush(stdout);

test=avcodec_encode_video2(c,&encoded,pFrameYUV,&got_packet);
if(got_packet)
{
	AVRational rat = {1,30};
	av_packet_rescale_ts(&encoded,rat, st->time_base);
	encoded.stream_index=st->index;
	printf("Got_packet= %d ",got_packet);
	test=av_interleaved_write_frame(oc,&encoded);
	printf("Test= %d ",test);
	printf("Write frame %3d (size=%5d)\n", i, encoded.size);
	av_free_packet(&encoded);
}
}

avcodec_close(c);
//av_free(c);
av_freep(&pFrameYUV->data[0]);
av_frame_free(&pFrameYUV);
count++;

}

What I have tried:

I've already tried to set the pts value, but it makes the Encoding fail!!!!!!!
Posted
Comments
Sergey Alexandrovich Kryukov 23-Jun-16 9:51am    
What "normal players"? Do you mean that you can play the file with the *play utility provided with the library but not other players?
What is your platform?

Note that there is no such thing as "MP4" file. Each media file is a combination of the media container and one or more channels based on different codecs. MPEG-4 is a whole set of different (and alternative standards). What exactly you are using? (You can find an answer if you use your *probe utility, in FFMpeg, it's called ffprobe, ffprobe.exe.) It can be such a simple thing as lack of codecs installed on your system. And some players, such as Windows Media Players are notoriously poor in terms of support of a set of modern standards.

—SA
Member 11549235 24-Jun-16 3:29am    
Hi,

The Video that was created can be opened with ffplay, but cannot be opened with Windows Media Player. I've tried to open another mp4 Container with WMP, it works.
KarstenK 26-Jun-16 13:37pm    
The windows media player is crappy. I have a lot of video which cant be played. Try VLC Player.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900