示例#1
0
文件: avi.c 项目: Oblong/x264vfw
static int open_file( char *psz_filename, hnd_t *p_handle, cli_output_opt_t *opt )
{
    avi_hnd_t *h;
    AVOutputFormat *mux_fmt;

    *p_handle = NULL;

    FILE *fh = fopen( psz_filename, "w" );
    if( !fh )
        return -1;
    int b_regular = x264_is_regular_file( fh );
    fclose( fh );
    if( !b_regular )
    {
        x264vfw_cli_log( opt->p_private, "avi", X264_LOG_ERROR, "AVI output is incompatible with non-regular file `%s'\n", psz_filename );
        return -1;
    }

    if( !(h = malloc( sizeof(avi_hnd_t) )) )
        return -1;
    memset( h, 0, sizeof(avi_hnd_t) );

    memcpy( &h->opt, opt, sizeof(cli_output_opt_t) );

    av_register_all();
    mux_fmt = av_guess_format( "avi", NULL, NULL );
    if( !mux_fmt )
    {
        close_file( h, 0, 0 );
        return -1;
    }

    h->mux_fc = avformat_alloc_context();
    if( !h->mux_fc )
    {
        close_file( h, 0, 0 );
        return -1;
    }
    h->mux_fc->oformat = mux_fmt;
    memset( h->mux_fc->filename, 0, sizeof(h->mux_fc->filename) );
    snprintf( h->mux_fc->filename, sizeof(h->mux_fc->filename) - 1, "%s", psz_filename );

    if( avio_open( &h->mux_fc->pb, psz_filename, AVIO_FLAG_WRITE ) < 0 )
    {
        close_file( h, 0, 0 );
        return -1;
    }

    *p_handle = h;

    return 0;
}
示例#2
0
static int write_frame( hnd_t handle, uint8_t *p_nalu, int i_size, x264_picture_t *p_picture )
{
    flv_hnd_t *p_flv = handle;
    flv_buffer *c = p_flv->c;

#define convert_timebase_ms( timestamp, timebase ) (int64_t)((timestamp) * (timebase) * 1000 + 0.5)

    if( !p_flv->i_framenum )
    {
        p_flv->i_delay_time = p_picture->i_dts * -1;
        if( !p_flv->opt.use_dts_compress && p_flv->i_delay_time )
            x264vfw_cli_log( p_flv->opt.p_private, "flv", X264_LOG_WARNING, "initial delay %"PRId64" ms\n",
                             convert_timebase_ms( p_picture->i_pts + p_flv->i_delay_time, p_flv->d_timebase ) );
    }

    int64_t dts;
    int64_t cts;
    int64_t offset;

    if( p_flv->opt.use_dts_compress )
    {
        if( p_flv->i_framenum == 1 )
            p_flv->i_init_delta = convert_timebase_ms( p_picture->i_dts + p_flv->i_delay_time, p_flv->d_timebase );
        dts = p_flv->i_framenum > p_flv->i_delay_frames
            ? convert_timebase_ms( p_picture->i_dts, p_flv->d_timebase )
            : p_flv->i_framenum * p_flv->i_init_delta / (p_flv->i_delay_frames + 1);
        cts = convert_timebase_ms( p_picture->i_pts, p_flv->d_timebase );
    }
    else
    {
        dts = convert_timebase_ms( p_picture->i_dts + p_flv->i_delay_time, p_flv->d_timebase );
        cts = convert_timebase_ms( p_picture->i_pts + p_flv->i_delay_time, p_flv->d_timebase );
    }
    offset = cts - dts;

    if( p_flv->i_framenum )
    {
        if( p_flv->i_prev_dts == dts )
            x264vfw_cli_log( p_flv->opt.p_private, "flv", X264_LOG_WARNING, "duplicate DTS %"PRId64" generated by rounding\n"
                             "               decoding framerate cannot exceed 1000fps\n", dts );
        if( p_flv->i_prev_cts == cts )
            x264vfw_cli_log( p_flv->opt.p_private, "flv", X264_LOG_WARNING, "duplicate CTS %"PRId64" generated by rounding\n"
                             "               composition framerate cannot exceed 1000fps\n", cts );
    }
    p_flv->i_prev_dts = dts;
    p_flv->i_prev_cts = cts;

    // A new frame - write packet header
    flv_put_byte( c, FLV_TAG_TYPE_VIDEO );
    flv_put_be24( c, 0 ); // calculated later
    flv_put_be24( c, dts );
    flv_put_byte( c, dts >> 24 );
    flv_put_be24( c, 0 );

    p_flv->start = c->d_cur;
    flv_put_byte( c, (p_picture->b_keyframe ? FLV_FRAME_KEY : FLV_FRAME_INTER) | FLV_CODECID_H264 );
    flv_put_byte( c, 1 ); // AVC NALU
    flv_put_be24( c, offset );

    if( p_flv->sei )
    {
        flv_append_data( c, p_flv->sei, p_flv->sei_len );
        free( p_flv->sei );
        p_flv->sei = NULL;
    }
    flv_append_data( c, p_nalu, i_size );

    unsigned length = c->d_cur - p_flv->start;
    flv_rewrite_amf_be24( c, length, p_flv->start - 10 );
    flv_put_be32( c, 11 + length ); // Last tag size
    CHECK( flv_flush_data( c ) );

    p_flv->i_framenum++;

    return i_size;
}