Hi to all I'm trying to encode some image into a mpg1 video file.
When I start the program I get lots of "buffer underflow" errors so:

[mpeg @ 0x9287f0]buffer underflow i=0 bufi=120 size=377
[mpeg @ 0x9287f0]buffer underflow i=0 bufi=452 size=1849
[mpeg @ 0x9287f0]buffer underflow i=0 bufi=215 size=377
[mpeg @ 0x9287f0]buffer underflow i=0 bufi=206 size=1849
[mpeg @ 0x9287f0]buffer underflow i=0 bufi=5 size=36
[mpeg @ 0x9287f0]buffer underflow i=0 bufi=342 size=377
[mpeg @ 0x9287f0]buffer underflow i=0 bufi=136 size=377
[mpeg @ 0x9287f0]buffer underflow i=0 bufi=91 size=377
[mpeg @ 0x9287f0]buffer underflow i=0 bufi=1734 size=1849
[mpeg @ 0x9287f0]buffer underflow i=0 bufi=258 size=377
[mpeg @ 0x9287f0]buffer underflow i=0 bufi=1488 size=1849

In the code I set these parameters:

void MovieRecorderBase::ffmpegOpenMovie( FrameRate frameRate )
{
    AVOutputFormat * format = 0;
    int bitrate = 0;
    int gopSize = 10;
    PixelFormat pixelFormat = PIX_FMT_YUV420P;
    int bFrames = 0;
    int extraFlags = 0;
    m_outputBufferSize = m_width * m_height;
    switch ( m_format ) {
        case HuffYUV: /* no intra frames */
            format = guess_format( "avi", NULL, NULL );
            m_fmt = guess_format( "avi", NULL, NULL );
            if ( format )
                format->video_codec = CODEC_ID_FFVHUFF;
            pixelFormat = PIX_FMT_YUV422P;
            m_outputBufferSize *= 3;
            break;

        case MPEG1:
            if ( frameRate < FR_NTSC_FILM ) {
                std::string str =  boost::str(
boost::format("MovieRecorderBase::ffmpegOpenMovie(): FrameRate too low for
MPEG1 (%d, use %d)" ) % frameRate % FR_NTSC_FILM );
                LOG_ERR((char *)str.c_str());
                return;
            }
            format = guess_format( "mpeg", NULL, NULL );
            m_fmt = guess_format( "mpeg", NULL, NULL );
            if ( format )
                format->video_codec = CODEC_ID_MPEG1VIDEO;
            bFrames = 1;
            gopSize = 12;
            bitrate = (int)(8 * 0.57 * m_width * m_height
                            * 25. * ((double)s_frameRateNumerator[frameRate]
                                     /
(double)s_frameRateDenominator[frameRate]) );
            break;

        case MPEG4:
            format = guess_format( "mp4", NULL, NULL );
            m_fmt = guess_format( "mp4", NULL, NULL );
            if ( format )
                format->video_codec = CODEC_ID_MPEG4;
            bFrames = 2;
        // FIXME: first fix the first blank frame bug, then uncomment
            // gopSize = 30;
            bitrate = (int)(8 * 0.35 * m_width * m_height
                            * 25. * ((double)s_frameRateNumerator[frameRate]
                                     /
(double)s_frameRateDenominator[frameRate]) );
            extraFlags = CODEC_FLAG_GLOBAL_HEADER
                         | CODEC_FLAG_4MV
                         | CODEC_FLAG_TRELLIS_QUANT
                         | CODEC_FLAG_AC_PRED;
            break;

        default:
            std::string str = boost::str( boost::format(
"MovieRecorderBase::ffmpegOpenMovie(): Unsupported movie format %d." ) %
m_format );
            LOG_ERR((char *)str.c_str());
            return;
    }
    if ( !format ) {
        std::string str = boost::str( boost::format(
"MovieRecorderBase::ffmpegOpenMovie(): Movie format %d not recognized by
ffmpeg." ) % m_format );
        LOG_ERR((char *)str.c_str());
        return;
    }
    //check for a video codec available
    if ( format->video_codec == CODEC_ID_NONE ) {
        std::string str = boost::str( boost::format(
"MovieRecorderBase::ffmpegOpenMovie(): Movie format %d not associated with
any video codec!" ) % m_format );
        LOG_ERR((char *)str.c_str());
        return;
    }
    // check for an audio codec available
    if ( format->audio_codec == CODEC_ID_NONE ) {
        std::string str = boost::str( boost::format(
"MovieRecorderBase::ffmpegOpenMovie(): Movie format %d not associated with
any audio codec!" ) % m_format );
        LOG_ERR((char *)str.c_str());
        return;
    }

    assert( !m_outputBuffer );
    m_outputBuffer = (unsigned char *)av_malloc( m_outputBufferSize );
    if ( !m_outputBuffer ) {
        LOG_ERR("MovieRecorderBase::constructor: Error allocating output
buffer.");
        return;
    }

    // allocate output media context
    assert( !m_context );
    m_context = av_alloc_format_context();
    if ( !m_context ) {
        LOG_ERR("MovieRecorderBase::ffmpegOpenMovie(): Cannot allocate
format context.");
        return;
    }

    m_context->oformat = format;
    std::string filename = m_movieNameBase + m_movieNameExtension;
    snprintf( m_context->filename, sizeof(m_context->filename), "%s",
filename.c_str() );

    // add video stream
    assert( !m_stream );
    m_stream = av_new_stream( m_context, 0 );
    if ( !m_stream ) {
        LOG_ERR("MovieRecorderBase::ffmpegOpenMovie(): Cannot add video
stream.");
        return;
    }

    AVCodecContext *codecCtx = m_stream->codec;
    codecCtx->codec_id = format->video_codec;
    codecCtx->codec_type = CODEC_TYPE_VIDEO;
    codecCtx->bit_rate = bitrate;
    codecCtx->bit_rate_tolerance = codecCtx->bit_rate / 5;// to see
    codecCtx->width = m_width;
    codecCtx->height = m_height;
    codecCtx->time_base.den =
s_frameRateNumerator[frameRate];//(AVRational){1/x}
    codecCtx->time_base.num = s_frameRateDenominator[frameRate];
    codecCtx->gop_size = gopSize;
    codecCtx->pix_fmt = pixelFormat;
    codecCtx->max_b_frames = bFrames;
    codecCtx->b_frame_strategy = 1;
    codecCtx->mb_decision = 2;
    codecCtx->strict_std_compliance = FF_COMPLIANCE_NORMAL;
    codecCtx->flags |= extraFlags;


In the switch I choose MPEG1 case.
For the bit rate I implement this formula
bpp = bitrate / ( image_width * image_height * 8 * frames_per_second )
bpp = "bits per pixel". I set bpp to 0.57 and determine  the bitrate.

What is wrong?
Regards

-- 
Franco
_______________________________________________
libav-user mailing list
[email protected]
https://lists.mplayerhq.hu/mailman/listinfo/libav-user

Reply via email to