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

📄 mp4.c

📁 video linux conference
💻 C
📖 第 1 页 / 共 5 页
字号:
                                 (double)p_sys->i_timescale );                return Seek( p_demux, i64 );            }            else return VLC_SUCCESS;        case DEMUX_GET_TIME:            pi64 = (int64_t*)va_arg( args, int64_t * );            if( p_sys->i_timescale > 0 )            {                *pi64 = (mtime_t)1000000 *                        (mtime_t)p_sys->i_time /                        (mtime_t)p_sys->i_timescale;            }            else *pi64 = 0;            return VLC_SUCCESS;        case DEMUX_SET_TIME:            i64 = (int64_t)va_arg( args, int64_t );            return Seek( p_demux, i64 );        case DEMUX_GET_LENGTH:            pi64 = (int64_t*)va_arg( args, int64_t * );            if( p_sys->i_timescale > 0 )            {                *pi64 = (mtime_t)1000000 *                        (mtime_t)p_sys->i_duration /                        (mtime_t)p_sys->i_timescale;            }            else *pi64 = 0;            return VLC_SUCCESS;        case DEMUX_GET_FPS:            msg_Warn( p_demux, "DEMUX_GET_FPS unimplemented !!" );            return VLC_EGENERIC;        case DEMUX_GET_META:        {            vlc_meta_t **pp_meta = (vlc_meta_t**)va_arg( args, vlc_meta_t** );            vlc_meta_t *meta;            MP4_Box_t  *p_udta   = MP4_BoxGet( p_sys->p_root, "/moov/udta" );            MP4_Box_t  *p_0xa9xxx;            if( p_udta == NULL )            {                return VLC_EGENERIC;            }            *pp_meta = meta = vlc_meta_New();            for( p_0xa9xxx = p_udta->p_first; p_0xa9xxx != NULL;                 p_0xa9xxx = p_0xa9xxx->p_next )            {                switch( p_0xa9xxx->i_type )                {                case FOURCC_0xa9nam: /* Full name */                    vlc_meta_Add( meta, VLC_META_TITLE,                                  p_0xa9xxx->data.p_0xa9xxx->psz_text );                    break;                case FOURCC_0xa9aut:                    vlc_meta_Add( meta, VLC_META_AUTHOR,                                  p_0xa9xxx->data.p_0xa9xxx->psz_text );                    break;                case FOURCC_0xa9ART:                    vlc_meta_Add( meta, VLC_META_ARTIST,                                  p_0xa9xxx->data.p_0xa9xxx->psz_text );                    break;                case FOURCC_0xa9cpy:                    vlc_meta_Add( meta, VLC_META_COPYRIGHT,                                  p_0xa9xxx->data.p_0xa9xxx->psz_text );                    break;                case FOURCC_0xa9day: /* Creation Date */                    vlc_meta_Add( meta, VLC_META_DATE,                                  p_0xa9xxx->data.p_0xa9xxx->psz_text );                    break;                case FOURCC_0xa9des: /* Description */                    vlc_meta_Add( meta, VLC_META_DESCRIPTION,                                  p_0xa9xxx->data.p_0xa9xxx->psz_text );                    break;                case FOURCC_0xa9gen: /* Genre */                    vlc_meta_Add( meta, VLC_META_GENRE,                                  p_0xa9xxx->data.p_0xa9xxx->psz_text );                    break;                case FOURCC_0xa9swr:                case FOURCC_0xa9inf: /* Information */                case FOURCC_0xa9alb: /* Album */                case FOURCC_0xa9dir: /* Director */                case FOURCC_0xa9dis: /* Disclaimer */                case FOURCC_0xa9enc: /* Encoded By */                case FOURCC_0xa9trk: /* Track */                case FOURCC_0xa9cmt: /* Commment */                case FOURCC_0xa9url: /* URL */                case FOURCC_0xa9req: /* Requirements */                case FOURCC_0xa9fmt: /* Original Format */                case FOURCC_0xa9dsa: /* Display Source As */                case FOURCC_0xa9hst: /* Host Computer */                case FOURCC_0xa9prd: /* Producer */                case FOURCC_0xa9prf: /* Performers */                case FOURCC_0xa9ope: /* Original Performer */                case FOURCC_0xa9src: /* Providers Source Content */                case FOURCC_0xa9wrt: /* Writer */                case FOURCC_0xa9com: /* Composer */                case FOURCC_WLOC:    /* Window Location */                    /* TODO one day, but they aren't really meaningfull */                    break;                default:                    break;                }            }            return VLC_SUCCESS;        }        case DEMUX_GET_TITLE_INFO:        case DEMUX_SET_NEXT_DEMUX_TIME:        case DEMUX_SET_GROUP:            return VLC_EGENERIC;        default:            msg_Warn( p_demux, "control query unimplemented !!!" );            return VLC_EGENERIC;    }}/***************************************************************************** * Close: frees unused data *****************************************************************************/static void Close ( vlc_object_t * p_this ){    unsigned int i_track;    demux_t *  p_demux = (demux_t *)p_this;    demux_sys_t *p_sys = p_demux->p_sys;    msg_Dbg( p_demux, "freeing all memory" );    MP4_BoxFree( p_demux->s, p_sys->p_root );    for( i_track = 0; i_track < p_sys->i_tracks; i_track++ )    {        MP4_TrackDestroy( p_demux, &p_sys->track[i_track] );    }    FREE( p_sys->track );    free( p_sys );}/**************************************************************************** * Local functions, specific to vlc ****************************************************************************//* now create basic chunk data, the rest will be filled by MP4_CreateSamplesIndex */static int TrackCreateChunksIndex( demux_t *p_demux,                                   mp4_track_t *p_demux_track ){    MP4_Box_t *p_co64; /* give offset for each chunk, same for stco and co64 */    MP4_Box_t *p_stsc;    unsigned int i_chunk;    unsigned int i_index, i_last;    if( ( !(p_co64 = MP4_BoxGet( p_demux_track->p_stbl, "stco" ) )&&          !(p_co64 = MP4_BoxGet( p_demux_track->p_stbl, "co64" ) ) )||        ( !(p_stsc = MP4_BoxGet( p_demux_track->p_stbl, "stsc" ) ) ))    {        return( VLC_EGENERIC );    }    p_demux_track->i_chunk_count = p_co64->data.p_co64->i_entry_count;    if( !p_demux_track->i_chunk_count )    {        msg_Warn( p_demux, "no chunk defined" );        return( VLC_EGENERIC );    }    p_demux_track->chunk = calloc( p_demux_track->i_chunk_count,                                   sizeof( mp4_chunk_t ) );    /* first we read chunk offset */    for( i_chunk = 0; i_chunk < p_demux_track->i_chunk_count; i_chunk++ )    {        mp4_chunk_t *ck = &p_demux_track->chunk[i_chunk];        ck->i_offset = p_co64->data.p_co64->i_chunk_offset[i_chunk];        ck->i_first_dts = 0;        ck->p_sample_count_dts = NULL;        ck->p_sample_delta_dts = NULL;        ck->p_sample_count_pts = NULL;        ck->p_sample_offset_pts = NULL;    }    /* now we read index for SampleEntry( soun vide mp4a mp4v ...)        to be used for the sample XXX begin to 1        We construct it begining at the end */    i_last = p_demux_track->i_chunk_count; /* last chunk proceded */    i_index = p_stsc->data.p_stsc->i_entry_count;    if( !i_index )    {        msg_Warn( p_demux, "cannot read chunk table or table empty" );        return( VLC_EGENERIC );    }    while( i_index-- )    {        for( i_chunk = p_stsc->data.p_stsc->i_first_chunk[i_index] - 1;             i_chunk < i_last; i_chunk++ )        {            p_demux_track->chunk[i_chunk].i_sample_description_index =                    p_stsc->data.p_stsc->i_sample_description_index[i_index];            p_demux_track->chunk[i_chunk].i_sample_count =                    p_stsc->data.p_stsc->i_samples_per_chunk[i_index];        }        i_last = p_stsc->data.p_stsc->i_first_chunk[i_index] - 1;    }    p_demux_track->chunk[0].i_sample_first = 0;    for( i_chunk = 1; i_chunk < p_demux_track->i_chunk_count; i_chunk++ )    {        p_demux_track->chunk[i_chunk].i_sample_first =            p_demux_track->chunk[i_chunk-1].i_sample_first +                p_demux_track->chunk[i_chunk-1].i_sample_count;    }    msg_Dbg( p_demux, "track[Id 0x%x] read %d chunk",             p_demux_track->i_track_ID, p_demux_track->i_chunk_count );    return VLC_SUCCESS;}static int TrackCreateSamplesIndex( demux_t *p_demux,                                    mp4_track_t *p_demux_track ){    MP4_Box_t *p_box;    MP4_Box_data_stsz_t *stsz;    MP4_Box_data_stts_t *stts;    /* TODO use also stss and stsh table for seeking */    /* FIXME use edit table */    int64_t i_sample;    int64_t i_chunk;    int64_t i_index;    int64_t i_index_sample_used;    int64_t i_last_dts;    /* Find stsz     *  Gives the sample size for each samples. There is also a stz2 table     *  (compressed form) that we need to implement TODO */    p_box = MP4_BoxGet( p_demux_track->p_stbl, "stsz" );    if( !p_box )    {        /* FIXME and stz2 */        msg_Warn( p_demux, "cannot find STSZ box" );        return VLC_EGENERIC;    }    stsz = p_box->data.p_stsz;    /* Find stts     *  Gives mapping between sample and decoding time     */    p_box = MP4_BoxGet( p_demux_track->p_stbl, "stts" );    if( !p_box )    {        msg_Warn( p_demux, "cannot find STTS box" );        return VLC_EGENERIC;    }    stts = p_box->data.p_stts;    /* Use stsz table to create a sample number -> sample size table */    p_demux_track->i_sample_count = stsz->i_sample_count;    if( stsz->i_sample_size )    {        /* 1: all sample have the same size, so no need to construct a table */        p_demux_track->i_sample_size = stsz->i_sample_size;        p_demux_track->p_sample_size = NULL;    }    else    {        /* 2: each sample can have a different size */        p_demux_track->i_sample_size = 0;        p_demux_track->p_sample_size =            calloc( p_demux_track->i_sample_count, sizeof( uint32_t ) );        for( i_sample = 0; i_sample < p_demux_track->i_sample_count; i_sample++ )        {            p_demux_track->p_sample_size[i_sample] =                    stsz->i_entry_size[i_sample];        }    }    /* Use stts table to create a sample number -> dts table.     * XXX: if we don't want to waste too much memory, we can't expand     *  the box! so each chunk will contain an "extract" of this table     *  for fast research (problem with raw stream where a sample is sometime     *  just channels*bits_per_sample/8 */    i_last_dts = 0;    i_index = 0; i_index_sample_used = 0;    for( i_chunk = 0; i_chunk < p_demux_track->i_chunk_count; i_chunk++ )    {        mp4_chunk_t *ck = &p_demux_track->chunk[i_chunk];        int64_t i_entry, i_sample_count, i;        /* save last dts */        ck->i_first_dts = i_last_dts;        /* count how many entries are needed for this chunk         * for p_sample_delta_dts and p_sample_count_dts */        i_sample_count = ck->i_sample_count;        i_entry = 0;        while( i_sample_count > 0 )        {            i_sample_count -= stts->i_sample_count[i_index+i_entry];            /* don't count already used sample in this entry */            if( i_entry == 0 )                i_sample_count += i_index_sample_used;            i_entry++;        }        /* allocate them */        ck->p_sample_count_dts = calloc( i_entry, sizeof( uint32_t ) );        ck->p_sample_delta_dts = calloc( i_entry, sizeof( uint32_t ) );        /* now copy */        i_sample_count = ck->i_sample_count;        for( i = 0; i < i_entry; i++ )        {            int64_t i_used;            int64_t i_rest;            i_rest = stts->i_sample_count[i_index] - i_index_sample_used;            i_used = __MIN( i_rest, i_sample_count );            i_index_sample_used += i_used;            i_sample_count -= i_used;            ck->p_sample_count_dts[i] = i_used;            ck->p_sample_delta_dts[i] = stts->i_sample_delta[i_index];            i_last_dts += i_used * ck->p_sample_delta_dts[i];            if( i_index_sample_used >= stts->i_sample_count[i_index] )            {                i_index++;                i_index_sample_used = 0;            }        }    }    /* Find ctts     *  Gives the delta between decoding time (dts) and composition table (pts)     */    p_box = MP4_BoxGet( p_demux_track->p_stbl, "ctts" );    if( p_box )    {        MP4_Box_data_ctts_t *ctts = p_box->data.p_ctts;        msg_Warn( p_demux, "CTTS table" );        /* Create pts-dts table per chunk */        i_index = 0; i_index_sample_used = 0;        for( i_chunk = 0; i_chunk < p_demux_track->i_chunk_count; i_chunk++ )        {            mp4_chunk_t *ck = &p_demux_track->chunk[i_chunk];            int64_t i_entry, i_sample_count, i;            /* count how many entries are needed for this chunk             * for p_sample_delta_dts and p_sample_count_dts */            i_sample_count = ck->i_sample_count;            i_entry = 0;            while( i_sample_count > 0 )            {                i_sample_count -= ctts->i_sample_count[i_index+i_entry];                /* don't count already used sample in this entry */                if( i_entry == 0 )                    i_sample_count += i_index_sample_used;                i_entry++;            }

⌨️ 快捷键说明

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