⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 avi.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 5 页
字号:
                                       i, tk->i_samplesize, tk->i_blocksize );                    tk->i_samplesize = tk->i_blocksize;                }                if( tk->i_codec == VLC_FOURCC( 'v', 'o', 'r', 'b' ) )                {                    tk->i_blocksize = 0; /* fix vorbis VBR decoding */                }                es_format_Init( &fmt, AUDIO_ES, tk->i_codec );                fmt.audio.i_channels        = p_auds->p_wf->nChannels;                fmt.audio.i_rate            = p_auds->p_wf->nSamplesPerSec;                fmt.i_bitrate               = p_auds->p_wf->nAvgBytesPerSec*8;                fmt.audio.i_blockalign      = p_auds->p_wf->nBlockAlign;                fmt.audio.i_bitspersample   = p_auds->p_wf->wBitsPerSample;                fmt.b_packetized            = !tk->i_blocksize;                msg_Dbg( p_demux,                    "stream[%d] audio(0x%x) %d channels %dHz %dbits",                    i, p_auds->p_wf->wFormatTag, p_auds->p_wf->nChannels,                    p_auds->p_wf->nSamplesPerSec,                     p_auds->p_wf->wBitsPerSample );                fmt.i_extra = __MIN( p_auds->p_wf->cbSize,                    p_auds->i_chunk_size - sizeof(WAVEFORMATEX) );                fmt.p_extra = tk->p_extra = malloc( fmt.i_extra );                if( !fmt.p_extra ) goto error;                memcpy( fmt.p_extra, &p_auds->p_wf[1], fmt.i_extra );                /* Rewrite the vorbis headers from Xiph-like format                 * to VLC internal format                 *                 * Xiph format:                 *  - 1st byte == N, is the number of packets - 1                 *  - Following bytes are the size of the N first packets:                 *      while( *p == 0xFF ) { size += 0xFF; p++ } size += *p;                 *      (the size of the last packet is the size of remaining                 *      data in the buffer)                 *  - Finally, all the packets concatenated                 *                 * VLC format:                 *  - Size of the packet on 16 bits (big endian) FIXME: should be 32 bits to be safe                 *  - The packet itself                 *  - Size of the next packet, and so on ...                 */                if( tk->i_codec == VLC_FOURCC( 'v', 'o', 'r', 'b' ) )                {                    uint8_t *p_extra = fmt.p_extra;                     size_t i_extra = fmt.i_extra;                    if( i_extra <= 1 ) break;                    if( *p_extra++ != 2 ) break; /* 3 packets - 1 = 2 */                    i_extra--;                    size_t i_identifier_len = 0;                    while( *p_extra == 0xFF )                    {                        i_identifier_len += 0xFF;                        p_extra++;                        if( --i_extra <= 1 ) break;                    }                    i_identifier_len += *p_extra++;                    if( i_identifier_len > --i_extra ) break;                    size_t i_comment_len = 0;                    while( *p_extra == 0xFF )                    {                        i_comment_len += 0xFF;                        p_extra++;                        if( --i_extra <= 1 ) break;                    }                    i_comment_len += *p_extra++;                    if( i_comment_len > --i_extra ) break;                    size_t i_cookbook_len = i_extra;                    size_t i_headers_size = 3  * 2 + i_identifier_len +                                            i_comment_len + i_cookbook_len;                    uint8_t *p_out = malloc( i_headers_size );                    if( !p_out ) goto error;                    free( fmt.p_extra );                    fmt.p_extra = tk->p_extra = p_out;                    fmt.i_extra = i_headers_size;                    #define copy_packet( len ) \                        *p_out++ = len >> 8; \                        *p_out++ = len & 0xFF; \                        memcpy( p_out, p_extra, len ); \                        p_out += len; \                        p_extra += len;                    copy_packet( i_identifier_len );                    copy_packet( i_comment_len );                    copy_packet( i_cookbook_len );                    #undef copy_packet                    break;                }                break;            case( AVIFOURCC_vids ):                tk->i_cat   = VIDEO_ES;                tk->i_codec = AVI_FourccGetCodec( VIDEO_ES,                                                  p_vids->p_bih->biCompression );                if( p_vids->p_bih->biCompression == 0x00 )                {                    switch( p_vids->p_bih->biBitCount )                    {                        case 32:                            tk->i_codec = VLC_FOURCC('R','V','3','2');                            break;                        case 24:                            tk->i_codec = VLC_FOURCC('R','V','2','4');                            break;                        case 16:                            /* tk->i_codec = VLC_FOURCC('R','V','1','6');*/                            /* break;*/                        case 15:                            tk->i_codec = VLC_FOURCC('R','V','1','5');                            break;                        case 9:                            tk->i_codec = VLC_FOURCC( 'Y', 'V', 'U', '9' ); /* <- TODO check that */                            break;                        case 8:                            tk->i_codec = VLC_FOURCC('Y','8','0','0');                            break;                    }                    es_format_Init( &fmt, VIDEO_ES, tk->i_codec );                    if( p_vids->p_bih->biBitCount == 24 )                    {                        /* This is in BGR format */                        fmt.video.i_bmask = 0x00ff0000;                        fmt.video.i_gmask = 0x0000ff00;                        fmt.video.i_rmask = 0x000000ff;                    }                }                else                {                    es_format_Init( &fmt, VIDEO_ES, p_vids->p_bih->biCompression );                    if( tk->i_codec == FOURCC_mp4v &&                        !strncasecmp( (char*)&p_strh->i_handler, "XVID", 4 ) )                    {                        fmt.i_codec = VLC_FOURCC( 'X', 'V', 'I', 'D' );                    }                }                tk->i_samplesize = 0;                fmt.video.i_width  = p_vids->p_bih->biWidth;                fmt.video.i_height = p_vids->p_bih->biHeight;                fmt.video.i_bits_per_pixel = p_vids->p_bih->biBitCount;                fmt.video.i_frame_rate = tk->i_rate;                fmt.video.i_frame_rate_base = tk->i_scale;                fmt.i_extra =                    __MIN( p_vids->p_bih->biSize - sizeof( BITMAPINFOHEADER ),                           p_vids->i_chunk_size - sizeof(BITMAPINFOHEADER) );                fmt.p_extra = &p_vids->p_bih[1];                msg_Dbg( p_demux, "stream[%d] video(%4.4s) %"PRIu32"x%"PRIu32" %dbpp %ffps",                         i, (char*)&p_vids->p_bih->biCompression,                         (uint32_t)p_vids->p_bih->biWidth,                         (uint32_t)p_vids->p_bih->biHeight,                         p_vids->p_bih->biBitCount,                         (float)tk->i_rate/(float)tk->i_scale );                if( p_vids->p_bih->biCompression == 0x00 )                {                    /* RGB DIB are coded from bottom to top */                    fmt.video.i_height =                        (unsigned int)(-(int)p_vids->p_bih->biHeight);                }                /* Extract palette from extradata if bpp <= 8                 * (assumes that extradata contains only palette but appears                 *  to be true for all palettized codecs we support) */                if( fmt.i_extra && fmt.video.i_bits_per_pixel <= 8 &&                    fmt.video.i_bits_per_pixel > 0 )                {                    int i;                    fmt.video.p_palette = calloc( sizeof(video_palette_t), 1 );                    fmt.video.p_palette->i_entries = 1;                    /* Apparently this is necessary. But why ? */                    fmt.i_extra =                        p_vids->i_chunk_size - sizeof(BITMAPINFOHEADER);                    for( i = 0; i < __MIN(fmt.i_extra/4, 256); i++ )                    {                        ((uint32_t *)&fmt.video.p_palette->palette[0][0])[i] =                            GetDWLE((uint32_t*)fmt.p_extra + i);                    }                }                break;            case( AVIFOURCC_txts):                tk->i_cat   = SPU_ES;                tk->i_codec = VLC_FOURCC( 's', 'u', 'b', 't' );                msg_Dbg( p_demux, "stream[%d] subtitles", i );                es_format_Init( &fmt, SPU_ES, tk->i_codec );                break;            case( AVIFOURCC_iavs):            case( AVIFOURCC_ivas):                p_sys->b_muxed = true;                msg_Dbg( p_demux, "stream[%d] iavs with handler %4.4s", i, (char *)&p_strh->i_handler );                if( p_strh->i_handler == FOURCC_dvsd ||                    p_strh->i_handler == FOURCC_dvhd ||                    p_strh->i_handler == FOURCC_dvsl ||                    p_strh->i_handler == FOURCC_dv25 ||                    p_strh->i_handler == FOURCC_dv50 )                {                    tk->p_out_muxed = stream_DemuxNew( p_demux, (char *)"rawdv", p_demux->out );                    if( !tk->p_out_muxed )                        msg_Err( p_demux, "could not load the DV parser" );                    else break;                }                free( tk );                continue;            case( AVIFOURCC_mids):                msg_Dbg( p_demux, "stream[%d] midi is UNSUPPORTED", i );            default:                msg_Warn( p_demux, "stream[%d] unknown type %4.4s", i, (char *)&p_strh->i_type );                free( tk );                continue;        }        if( p_strn )        {            /* The charset of p_strn is undefined */            EnsureUTF8( p_strn->p_str );            fmt.psz_description = strdup( p_strn->p_str );        }        if( tk->p_out_muxed == NULL )            tk->p_es = es_out_Add( p_demux->out, &fmt );        TAB_APPEND( p_sys->i_track, p_sys->track, tk );    }    if( p_sys->i_track <= 0 )    {        msg_Err( p_demux, "no valid track" );        goto error;    }    i_do_index =  config_GetInt( p_demux, "avi-index" );    if( i_do_index == 1 ) /* Always fix */    {aviindex:        if( p_sys->b_seekable )        {            AVI_IndexCreate( p_demux );        }        else        {            msg_Warn( p_demux, "cannot create index (unseekable stream)" );            AVI_IndexLoad( p_demux );        }    }    else    {        AVI_IndexLoad( p_demux );    }    /* *** movie length in sec *** */    p_sys->i_length = AVI_MovieGetLength( p_demux );    if( p_sys->i_length < (mtime_t)p_avih->i_totalframes *                          (mtime_t)p_avih->i_microsecperframe /                          (mtime_t)1000000 )    {        msg_Warn( p_demux, "broken or missing index, 'seek' will be "                           "approximative or will exhibit strange behavior" );        if( i_do_index == 0 && !b_index )        {            if( !p_sys->b_seekable ) {                b_index = true;                goto aviindex;            }            int i_create;            i_create = intf_UserYesNo( p_demux, _("AVI Index") ,                        _( "This AVI file is broken. Seeking will not "                        "work correctly.\nDo you want to "                        "try to repair it?\n\nThis might take a long time." ),                        _( "Repair" ), _( "Don't repair" ), _( "Cancel") );            if( i_create == DIALOG_OK_YES )            {                b_index = true;                msg_Dbg( p_demux, "Fixing AVI index" );                goto aviindex;            }            else if( i_create == DIALOG_CANCELLED )            {                /* Kill input */                vlc_object_kill( p_demux->p_parent );                goto error;            }        }    }    /* fix some BeOS MediaKit generated file */    for( i = 0 ; i < p_sys->i_track; i++ )    {        avi_track_t         *tk = p_sys->track[i];        avi_chunk_list_t    *p_strl;        avi_chunk_strh_t    *p_strh;        avi_chunk_strf_auds_t    *p_auds;        if( tk->i_cat != AUDIO_ES )        {            continue;        }        if( tk->i_idxnb < 1 ||            tk->i_scale != 1 ||            tk->i_samplesize != 0 )        {            continue;        }        p_strl = AVI_ChunkFind( p_hdrl, AVIFOURCC_strl, i );        p_strh = AVI_ChunkFind( p_strl, AVIFOURCC_strh, 0 );        p_auds = AVI_ChunkFind( p_strl, AVIFOURCC_strf, 0 );        if( p_auds->p_wf->wFormatTag != WAVE_FORMAT_PCM &&            (unsigned int)tk->i_rate == p_auds->p_wf->nSamplesPerSec )        {            int64_t i_track_length =                tk->p_index[tk->i_idxnb-1].i_length +                tk->p_index[tk->i_idxnb-1].i_lengthtotal;            mtime_t i_length = (mtime_t)p_avih->i_totalframes *                               (mtime_t)p_avih->i_microsecperframe;            if( i_length == 0 )            {                msg_Warn( p_demux, "track[%d] cannot be fixed (BeOS MediaKit generated)", i );                continue;            }            tk->i_samplesize = 1;            tk->i_rate       = i_track_length  * (int64_t)1000000/ i_length;            msg_Warn( p_demux, "track[%d] fixed with rate=%d scale=%d (BeOS MediaKit generated)", i, tk->i_rate, tk->i_scale );        }    }    if( p_sys->b_seekable )    {        /* we have read all chunk so go back to movi */        stream_Seek( p_demux->s, p_movi->i_chunk_pos );    }    /* Skip movi header */    stream_Read( p_demux->s, NULL, 12 );    p_sys->i_movi_begin = p_movi->i_chunk_pos;    return VLC_SUCCESS;error:    if( p_sys->meta )    {        vlc_meta_Delete( p_sys->meta );    }    AVI_ChunkFreeRoot( p_demux->s, &p_sys->ck_root );    free( p_sys );    return VLC_EGENERIC;}/***************************************************************************** * Close: frees unused data *****************************************************************************/static void Close ( vlc_object_t * p_this ){    demux_t *    p_demux = (demux_t *)p_this;    unsigned int i;    demux_sys_t *p_sys = p_demux->p_sys  ;    for( i = 0; i < p_sys->i_track; i++ )    {        if( p_sys->track[i] )        {            if( p_sys->track[i]->p_out_muxed )                stream_DemuxDelete( p_sys->track[i]->p_out_muxed );            free( p_sys->track[i]->p_index );            free( p_sys->track[i]->p_extra );            free( p_sys->track[i] );        }    }    free( p_sys->track );    AVI_ChunkFreeRoot( p_demux->s, &p_sys->ck_root );    vlc_meta_Delete( p_sys->meta );    free( p_sys );}/***************************************************************************** * Demux_Seekable: reads and demuxes data packets for stream seekable ***************************************************************************** * AVIDemux: reads and demuxes data packets ***************************************************************************** * Returns -1 in case of error, 0 in case of EOF, 1 otherwise *****************************************************************************/typedef struct{    bool b_ok;    int i_toread;    off_t i_posf; /* where we will read :                   if i_idxposb == 0 : begining of chunk (+8 to acces data)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -