[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