[Sorry this is a repost, as the code indentation was scrubbed away in the previous post. Please bear with a newbie. ]
I am have trouble encoding an H264 video correctly using FFmpeg libav. I could not play the encoded video in VLC media player, and although I could play the video on MPC-HC the time shows 00:00/00:00. Clearly I'm missing something. The Media info from MPC-HC shows this: General Format : AVC Format/Info : Advanced Video Codec File size : 110 KiB Duration : 2s 400ms Overall bit rate : 375 Kbps Writing library : x264 core 148 r2665 a01e339 Encoding settings : cabac=0 / ref=3 / deblock=1:0:0 / analyse=0x1:0x111 / me=hex / subme=7 / psy=1 / psy_rd=1.00:0.00 / mixed_ref=1 / me_range=16 / chroma_me=1 / trellis=1 / 8x8dct=0 / cqm=0 / deadzone=21,11 / fast_pskip=1 / chroma_qp_offset=-2 / threads=7 / lookahead_threads=1 / sliced_threads=0 / nr=0 / decimate=1 / interlaced=0 / bluray_compat=0 / constrained_intra=0 / bframes=0 / weightp=0 / keyint=12 / keyint_min=1 / scenecut=40 / intra_refresh=0 / rc_lookahead=12 / rc=abr / mbtree=1 / bitrate=2000 / ratetol=1.0 / qcomp=0.60 / qpmin=0 / qpmax=69 / qpstep=4 / ip_ratio=1.40 / aq=1:1.00 Video Format : AVC Format/Info : Advanced Video Codec Format profile : Baseline@L2.1 Format settings, CABAC : No Format settings, ReFrames : 3 frames Format settings, GOP : M=1, N=12 Duration : 2s 400ms Bit rate : 2 000 Kbps Width : 320 pixels Height : 240 pixels Display aspect ratio : 4:3 Frame rate mode : Variable Frame rate : 20.833 fps Color space : YUV Chroma subsampling : 4:2:0 Bit depth : 8 bits Scan type : Progressive Bits/(Pixel*Frame) : 1.250 Stream size : 586 KiB Writing library : x264 core 148 r2665 a01e339 Encoding settings : cabac=0 / ref=3 / deblock=1:0:0 / analyse=0x1:0x111 / me=hex / subme=7 / psy=1 / psy_rd=1.00:0.00 / mixed_ref=1 / me_range=16 / chroma_me=1 / trellis=1 / 8x8dct=0 / cqm=0 / deadzone=21,11 / fast_pskip=1 / chroma_qp_offset=-2 / threads=7 / lookahead_threads=1 / sliced_threads=0 / nr=0 / decimate=1 / interlaced=0 / bluray_compat=0 / constrained_intra=0 / bframes=0 / weightp=0 / keyint=12 / keyint_min=1 / scenecut=40 / intra_refresh=0 / rc_lookahead=12 / rc=abr / mbtree=1 / bitrate=2000 / ratetol=1.0 / qcomp=0.60 / qpmin=0 / qpmax=69 / qpstep=4 / ip_ratio=1.40 / aq=1:1.00 I noticed something odd in the above info: - The frame rate is 20.833 fps, instead of the specified 10 fps. - Duration of 2s 400ms did not seem right either, since the video played for more than 4s. Also, (AVFrame* picture)->pict_type is always set to AV_PICTURE_TYPE_NONE. Is this normal? The library that I'm using is ffmpeg-20160219-git-98a0053-win32-dev. I would really really appreciate if you could help me out of this confusion. /* * Video encoding example */ char filename[] = "test.mp4"; int main(int argc, char argv) { AVCodec *codec = NULL; AVCodecContext *codecCtx= NULL; AVFormatContext *pFormatCtx = NULL; AVStream * pVideoStream = NULL; AVFrame *picture = NULL; int i, x, y, // ret, // Return value got_packet_ptr; // Data encoded into packet printf("Video encoding\n"); // Register all formats and codecs av_register_all(); // allocate context pFormatCtx = avformat_alloc_context(); memcpy(pFormatCtx->filename,filename, min(strlen(filename), sizeof(pFormatCtx->filename))); // guess format pFormatCtx->oformat = av_guess_format("h264", NULL, NULL); if (NULL==pFormatCtx->oformat) { cerr << "Could not guess output format" << endl; return -1; } // Find the codec. codec = avcodec_find_encoder(pFormatCtx->oformat->video_codec); if (codec == NULL) { fprintf(stderr, "Codec not found\n"); return -1; } // Set context int framerate = 10; codecCtx = avcodec_alloc_context3(codec); avcodec_get_context_defaults3(codecCtx, codec); codecCtx->pix_fmt = AV_PIX_FMT_YUV420P; codecCtx->profile = FF_PROFILE_H264_BASELINE; // Resolution must be a multiple of two. codecCtx->width = 320; codecCtx->height = 240; codecCtx->bit_rate = 2000000; codecCtx->time_base.den = framerate; codecCtx->time_base.num = 1; codecCtx->gop_size = 12; // emit one intra frame every twelve frames at most // Open the codec. if (avcodec_open2(codecCtx, codec, NULL) < 0) { printf("Cannot open video codec\n"); return -1; } // Add stream to pFormatCtx pVideoStream = avformat_new_stream(pFormatCtx, codec); if (!pVideoStream) { printf("Cannot add new video stream\n"); return -1; } pVideoStream->codec = codecCtx; pVideoStream->time_base.den = framerate; pVideoStream->time_base.num = 1; if (avio_open2(&pFormatCtx->pb, filename, AVIO_FLAG_WRITE, NULL, NULL) < 0) { printf("Cannot open file\n"); return -1; } // Write file header. avformat_write_header(pFormatCtx, NULL); // Create frame picture= av_frame_alloc(); picture->format = codecCtx->pix_fmt; picture->width = codecCtx->width; picture->height = codecCtx->height; int bufferImgSize = av_image_get_buffer_size(codecCtx->pix_fmt, codecCtx->width, codecCtx->height,1); av_image_alloc(picture->data, picture->linesize, codecCtx->width, codecCtx->height, codecCtx->pix_fmt, 32); AVPacket avpkt; /* encode 1 second of video */ for(i=0;i<50;i++) { /* prepare a dummy image */ /* Y */ for(y=0;y<codecCtx->height;y++) { for(x=0;x<codecCtx->width;x++) { picture->data[0][y * picture->linesize[0] + x] = x + y + i * 3; } } /* Cb and Cr */ for(y=0;y<codecCtx->height/2;y++) { for(x=0;x<codecCtx->width/2;x++) { picture->data[1][y * picture->linesize[1] + x] = 128 + y + i * 2; picture->data[2][y * picture->linesize[2] + x] = 64 + x + i * 5; } } // Get timestamp picture->pts = (float) i * (1000.0/(float)(codecCtx->time_base.den)) * 90; // Encode frame to packet av_init_packet(&avpkt); got_packet_ptr = 0; int error = avcodec_encode_video2(codecCtx, &avpkt, picture, &got_packet_ptr); if (!error && got_packet_ptr > 0) { // Write packet with frame. ret = (av_interleaved_write_frame(pFormatCtx, &avpkt) == 0); } av_packet_unref(&avpkt); } // Flush remaining encoded data while(1) { av_init_packet(&avpkt); got_packet_ptr = 0; // Encode frame to packet. int error = avcodec_encode_video2(codecCtx, &avpkt, NULL, &got_packet_ptr); if (!error && got_packet_ptr > 0) { // Write packet with frame. ret = (av_interleaved_write_frame(pFormatCtx, &avpkt) == 0); } else { break; } av_packet_unref(&avpkt); } av_write_trailer(pFormatCtx); av_packet_unref(&avpkt); av_frame_free(&picture); avcodec_close(codecCtx); av_free(codecCtx); cin.get(); } On Wed, 30 Mar 2016 at 17:17 Yu Ang Tan <iso...@gmail.com> wrote: > I am have trouble encoding an H264 video correctly using FFmpeg libav. I > could not play the encoded video in VLC media player, and although I could > play the video on MPC-HC the time shows 00:00/00:00. Clearly I'm missing > something. > > The Media info from MPC-HC shows this: > > General > Format : AVC > Format/Info : Advanced Video Codec > File size : 110 KiB > Duration : 2s 400ms > Overall bit rate : 375 Kbps > Writing library : x264 core 148 r2665 a01e339 > Encoding settings : cabac=0 / ref=3 / deblock=1:0:0 / > analyse=0x1:0x111 / me=hex / subme=7 / psy=1 / psy_rd=1.00:0.00 / > mixed_ref=1 / me_range=16 / chroma_me=1 / trellis=1 / 8x8dct=0 / cqm=0 / > deadzone=21,11 / fast_pskip=1 / chroma_qp_offset=-2 / threads=7 / > lookahead_threads=1 / sliced_threads=0 / nr=0 / decimate=1 / interlaced=0 / > bluray_compat=0 / constrained_intra=0 / bframes=0 / weightp=0 / keyint=12 / > keyint_min=1 / scenecut=40 / intra_refresh=0 / rc_lookahead=12 / rc=abr / > mbtree=1 / bitrate=2000 / ratetol=1.0 / qcomp=0.60 / qpmin=0 / qpmax=69 / > qpstep=4 / ip_ratio=1.40 / aq=1:1.00 > > Video > Format : AVC > Format/Info : Advanced Video Codec > Format profile : Baseline@L2.1 > Format settings, CABAC : No > Format settings, ReFrames : 3 frames > Format settings, GOP : M=1, N=12 > Duration : 2s 400ms > Bit rate : 2 000 Kbps > Width : 320 pixels > Height : 240 pixels > Display aspect ratio : 4:3 > Frame rate mode : Variable > Frame rate : 20.833 fps > Color space : YUV > Chroma subsampling : 4:2:0 > Bit depth : 8 bits > Scan type : Progressive > Bits/(Pixel*Frame) : 1.250 > Stream size : 586 KiB > Writing library : x264 core 148 r2665 a01e339 > Encoding settings : cabac=0 / ref=3 / deblock=1:0:0 / > analyse=0x1:0x111 / me=hex / subme=7 / psy=1 / psy_rd=1.00:0.00 / > mixed_ref=1 / me_range=16 / chroma_me=1 / trellis=1 / 8x8dct=0 / cqm=0 / > deadzone=21,11 / fast_pskip=1 / chroma_qp_offset=-2 / threads=7 / > lookahead_threads=1 / sliced_threads=0 / nr=0 / decimate=1 / interlaced=0 / > bluray_compat=0 / constrained_intra=0 / bframes=0 / weightp=0 / keyint=12 / > keyint_min=1 / scenecut=40 / intra_refresh=0 / rc_lookahead=12 / rc=abr / > mbtree=1 / bitrate=2000 / ratetol=1.0 / qcomp=0.60 / qpmin=0 / qpmax=69 / > qpstep=4 / ip_ratio=1.40 / aq=1:1.00 > > I noticed something odd in the above info: > - The frame rate is 20.833 fps, instead of the specified 10 fps. > - Duration of 2s 400ms did not seem right either, since the video played > for more than 4s. > > Also, (AVFrame* picture)->pict_type is always set to AV_PICTURE_TYPE_NONE. > Is this normal? > > The library that I'm using is ffmpeg-20160219-git-98a0053-win32-dev. I > would really really appreciate if you could help me out of this confusion. > > /* > * Video encoding example > */ > char filename[] = "test.mp4"; > int main(int argc, char argv) > { > AVCodec *codec = NULL; > AVCodecContext *codecCtx= NULL; > AVFormatContext *pFormatCtx = NULL; > AVStream * pVideoStream = NULL; > AVFrame *picture = NULL; > int i, x, y, // > ret, // Return value > got_packet_ptr; // Data encoded into packet > > printf("Video encoding\n"); > // Register all formats and codecs > av_register_all(); > > // allocate context > pFormatCtx = avformat_alloc_context(); > memcpy(pFormatCtx->filename,filename, > min(strlen(filename), sizeof(pFormatCtx->filename))); > // guess format > pFormatCtx->oformat = av_guess_format("h264", NULL, NULL); > if (NULL==pFormatCtx->oformat) > { > cerr << "Could not guess output format" << endl; > return -1; > } > // Find the codec. > codec = avcodec_find_encoder(pFormatCtx->oformat->video_codec); > if (codec == NULL) { > fprintf(stderr, "Codec not found\n"); > return -1; > } > // Set context > int framerate = 10; > codecCtx = avcodec_alloc_context3(codec); > avcodec_get_context_defaults3(codecCtx, codec); > codecCtx->pix_fmt = AV_PIX_FMT_YUV420P; > codecCtx->profile = FF_PROFILE_H264_BASELINE; > // Resolution must be a multiple of two. > codecCtx->width = 320; > codecCtx->height = 240; > codecCtx->bit_rate = 2000000; > codecCtx->time_base.den = framerate; > codecCtx->time_base.num = 1; > codecCtx->gop_size = 12; // emit one intra frame every twelve frames at > most > // Open the codec. > if (avcodec_open2(codecCtx, codec, NULL) < 0) > { > printf("Cannot open video codec\n"); > return -1; > } > // Add stream to pFormatCtx > pVideoStream = avformat_new_stream(pFormatCtx, codec); > if (!pVideoStream) > { > printf("Cannot add new video stream\n"); > return -1; > } > pVideoStream->codec = codecCtx; > pVideoStream->time_base.den = framerate; > pVideoStream->time_base.num = 1; > > if (avio_open2(&pFormatCtx->pb, filename, AVIO_FLAG_WRITE, NULL, NULL) < > 0) > { > printf("Cannot open file\n"); > return -1; > } > // Write file header. > avformat_write_header(pFormatCtx, NULL); > // Create frame > picture= av_frame_alloc(); > picture->format = codecCtx->pix_fmt; > picture->width = codecCtx->width; > picture->height = codecCtx->height; > > int bufferImgSize = av_image_get_buffer_size(codecCtx->pix_fmt, > codecCtx->width, > codecCtx->height,1); > av_image_alloc(picture->data, picture->linesize, codecCtx->width, > codecCtx->height, codecCtx->pix_fmt, 32); > > AVPacket avpkt; > > /* encode 1 second of video */ > for(i=0;i<50;i++) > { > /* prepare a dummy image */ > /* Y */ > for(y=0;y<codecCtx->height;y++) > { > for(x=0;x<codecCtx->width;x++) > { > picture->data[0][y * picture->linesize[0] + x] = x + y + i * 3; > } > } > /* Cb and Cr */ > for(y=0;y<codecCtx->height/2;y++) > { > for(x=0;x<codecCtx->width/2;x++) > { > picture->data[1][y * picture->linesize[1] + x] = 128 + y + i * 2; > picture->data[2][y * picture->linesize[2] + x] = 64 + x + i * 5; > } > } > > // Get timestamp > picture->pts = (float) i * (1000.0/(float)(codecCtx->time_base.den)) * 90; > > // Encode frame to packet > av_init_packet(&avpkt); > got_packet_ptr = 0; > int error = avcodec_encode_video2(codecCtx, &avpkt, picture, > &got_packet_ptr); > if (!error && got_packet_ptr > 0) > { > // Write packet with frame. > ret = (av_interleaved_write_frame(pFormatCtx, &avpkt) == 0); > } > av_packet_unref(&avpkt); > } > > // Flush remaining encoded data > while(1) > { > av_init_packet(&avpkt); > got_packet_ptr = 0; > // Encode frame to packet. > int error = avcodec_encode_video2(codecCtx, &avpkt, NULL, &got_packet_ptr); > if (!error && got_packet_ptr > 0) > { > // Write packet with frame. > ret = (av_interleaved_write_frame(pFormatCtx, &avpkt) == 0); > } > else > { > break; > } > av_packet_unref(&avpkt); > } > av_write_trailer(pFormatCtx); > av_packet_unref(&avpkt); > av_frame_free(&picture); > avcodec_close(codecCtx); > av_free(codecCtx); > > cin.get(); > } >
_______________________________________________ Libav-user mailing list Libav-user@ffmpeg.org http://ffmpeg.org/mailman/listinfo/libav-user