[Libav-user] H264 Encoding - Could not play video using VLC Player
Yu Ang Tan
isoboy at gmail.com
Wed Mar 30 08:26:36 CEST 2016
[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 at 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 <isoboy at 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 at 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();
> }
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://ffmpeg.org/pipermail/libav-user/attachments/20160330/53038574/attachment.html>
More information about the Libav-user
mailing list