[Libav-user] H264 Encoding - Could not play video using VLC Player

Yu Ang Tan isoboy at gmail.com
Wed Mar 30 08:17:27 CEST 2016


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/603e33a4/attachment.html>


More information about the Libav-user mailing list