FFmpeg版本:3.4

在FFmpeg中,每一种文件容器格式都对应一种AVInputFormat 结构,位于源码中libavformat文件夹中。当调用avformat_open_input的时候,FFmpeg会根据媒体封装格式的特点(主要是根据AVInputFormat结构的read_probe函数根据传入的一段buffer来判断传入的文件是否能被解析为该AVInputFormat对应的容器格式),对全部已知的格式进行判断并设置一个分值,取其中最高的分值来关联到一种文件容器格式。
我们通过下面的函数调用堆栈信息来分析avformat_open_input是怎样一步步的关联到具体的文件容器格式的。

static int init_input(AVFormatContext *s, const char *filename,
AVDictionary **options)
{
//...
return av_probe_input_buffer2(s->pb, &s->iformat, filename,
s, , s->format_probesize);
}
int av_probe_input_buffer2(AVIOContext *pb, AVInputFormat **fmt,
const char *filename, void *logctx,
unsigned int offset, unsigned int max_probe_size)
{
//...
//把AVFormatContext和具体的AVInputFormat联系起来了
*fmt = av_probe_input_format2(&pd, , &score);
//...
}

FFmpeg中实现探测的函数是av_probe_input_buffer2和av_probe_input_format3。其核心代码如下:

//遍历所有的Demuxer
while ((fmt1 = av_demuxer_iterate(&i))) {
if (!is_opened == !(fmt1->flags & AVFMT_NOFILE) && strcmp(fmt1->name, "image2"))
continue;
score = ;
if (fmt1->read_probe) {
score = fmt1->read_probe(&lpd);
if (score)
av_log(NULL, AV_LOG_TRACE, "Probing %s score:%d size:%d\n", fmt1->name, score, lpd.buf_size);
if (fmt1->extensions && av_match_ext(lpd.filename, fmt1->extensions)) {
switch (nodat) {
case NO_ID3:
score = FFMAX(score, );
break;
case ID3_GREATER_PROBE:
case ID3_ALMOST_GREATER_PROBE:
score = FFMAX(score, AVPROBE_SCORE_EXTENSION / - );
break;
case ID3_GREATER_MAX_PROBE:
score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
break;
}
}
} else if (fmt1->extensions) {
if (av_match_ext(lpd.filename, fmt1->extensions))
score = AVPROBE_SCORE_EXTENSION;
}
if (av_match_name(lpd.mime_type, fmt1->mime_type)) {
if (AVPROBE_SCORE_MIME > score) {
av_log(NULL, AV_LOG_DEBUG, "Probing %s score:%d increased to %d due to MIME type\n", fmt1->name, score, AVPROBE_SCORE_MIME);
score = AVPROBE_SCORE_MIME;
}
}
if (score > score_max) {
score_max = score;
fmt = (AVInputFormat*)fmt1;
} else if (score == score_max)
fmt = NULL;
}

上面代码的原理就是优先使用demuxer的read_probe函数,然后参考文件名的后缀名来关联某个AVInputFormat。

const AVInputFormat *av_demuxer_iterate(void **opaque)
{
static const uintptr_t size = sizeof(demuxer_list)/sizeof(demuxer_list[]) - ;
uintptr_t i = (uintptr_t)*opaque;
const AVInputFormat *f = NULL; if (i < size) {
//遍历demuxer_list中的所有demuxer
f = demuxer_list[i];
} else if (outdev_list) {
f = indev_list[i - size];
} if (f)
*opaque = (void*)(i + );
return f;
}

demuxer_list数组定义在libavformat/demuxer_list.c中,该文件是编译FFMPEG configure的时候生成的

print_enabled_components libavformat/demuxer_list.c AVInputFormat demuxer_list $DEMUXER_LIST
static const AVInputFormat * const demuxer_list[] = {
&ff_aa_demuxer,
&ff_aac_demuxer,
&ff_ac3_demuxer,
&ff_acm_demuxer,
&ff_act_demuxer,
&ff_adf_demuxer,
&ff_adp_demuxer,
&ff_ads_demuxer,
&ff_adx_demuxer,
&ff_aea_demuxer,
&ff_afc_demuxer,
&ff_aiff_demuxer,
&ff_aix_demuxer,
&ff_amr_demuxer,
&ff_amrnb_demuxer,
&ff_amrwb_demuxer,
&ff_anm_demuxer,
&ff_apc_demuxer,
&ff_ape_demuxer,
&ff_apng_demuxer,
&ff_aptx_demuxer,
&ff_aptx_hd_demuxer,
&ff_aqtitle_demuxer,
&ff_asf_demuxer,
&ff_asf_o_demuxer,
&ff_ass_demuxer,
&ff_ast_demuxer,
&ff_au_demuxer,
&ff_avi_demuxer,
&ff_avr_demuxer,
&ff_avs_demuxer,
&ff_bethsoftvid_demuxer,
&ff_bfi_demuxer,
&ff_bintext_demuxer,
&ff_bink_demuxer,
&ff_bit_demuxer,
&ff_bmv_demuxer,
&ff_bfstm_demuxer,
&ff_brstm_demuxer,
&ff_boa_demuxer,
&ff_c93_demuxer,
&ff_caf_demuxer,
&ff_cavsvideo_demuxer,
&ff_cdg_demuxer,
&ff_cdxl_demuxer,
&ff_cine_demuxer,
&ff_codec2_demuxer,
&ff_codec2raw_demuxer,
&ff_concat_demuxer,
&ff_data_demuxer,
&ff_daud_demuxer,
&ff_dcstr_demuxer,
&ff_dfa_demuxer,
&ff_dirac_demuxer,
&ff_dnxhd_demuxer,
&ff_dsf_demuxer,
&ff_dsicin_demuxer,
&ff_dss_demuxer,
&ff_dts_demuxer,
&ff_dtshd_demuxer,
&ff_dv_demuxer,
&ff_dvbsub_demuxer,
&ff_dvbtxt_demuxer,
&ff_dxa_demuxer,
&ff_ea_demuxer,
&ff_ea_cdata_demuxer,
&ff_eac3_demuxer,
&ff_epaf_demuxer,
&ff_ffmetadata_demuxer,
&ff_filmstrip_demuxer,
&ff_fits_demuxer,
&ff_flac_demuxer,
&ff_flic_demuxer,
&ff_flv_demuxer,
&ff_live_flv_demuxer,
&ff_fourxm_demuxer,
&ff_frm_demuxer,
&ff_fsb_demuxer,
&ff_g722_demuxer,
&ff_g723_1_demuxer,
&ff_g726_demuxer,
&ff_g726le_demuxer,
&ff_g729_demuxer,
&ff_gdv_demuxer,
&ff_genh_demuxer,
&ff_gif_demuxer,
&ff_gsm_demuxer,
&ff_gxf_demuxer,
&ff_h261_demuxer,
&ff_h263_demuxer,
&ff_h264_demuxer,
&ff_hevc_demuxer,
&ff_hls_demuxer,
&ff_hnm_demuxer,
&ff_ico_demuxer,
&ff_idcin_demuxer,
&ff_idf_demuxer,
&ff_iff_demuxer,
&ff_ilbc_demuxer,
&ff_image2_demuxer,
&ff_image2pipe_demuxer,
&ff_image2_alias_pix_demuxer,
&ff_image2_brender_pix_demuxer,
&ff_ingenient_demuxer,
&ff_ipmovie_demuxer,
&ff_ircam_demuxer,
&ff_iss_demuxer,
&ff_iv8_demuxer,
&ff_ivf_demuxer,
&ff_ivr_demuxer,
&ff_jacosub_demuxer,
&ff_jv_demuxer,
&ff_lmlm4_demuxer,
&ff_loas_demuxer,
&ff_lrc_demuxer,
&ff_lvf_demuxer,
&ff_lxf_demuxer,
&ff_m4v_demuxer,
&ff_matroska_demuxer,
&ff_mgsts_demuxer,
&ff_microdvd_demuxer,
&ff_mjpeg_demuxer,
&ff_mjpeg_2000_demuxer,
&ff_mlp_demuxer,
&ff_mlv_demuxer,
&ff_mm_demuxer,
&ff_mmf_demuxer,
&ff_mov_demuxer,
&ff_mp3_demuxer,
&ff_mpc_demuxer,
&ff_mpc8_demuxer,
&ff_mpegps_demuxer,
&ff_mpegts_demuxer,
&ff_mpegtsraw_demuxer,
&ff_mpegvideo_demuxer,
&ff_mpjpeg_demuxer,
&ff_mpl2_demuxer,
&ff_mpsub_demuxer,
&ff_msf_demuxer,
&ff_msnwc_tcp_demuxer,
&ff_mtaf_demuxer,
&ff_mtv_demuxer,
&ff_musx_demuxer,
&ff_mv_demuxer,
&ff_mvi_demuxer,
&ff_mxf_demuxer,
&ff_mxg_demuxer,
&ff_nc_demuxer,
&ff_nistsphere_demuxer,
&ff_nsp_demuxer,
&ff_nsv_demuxer,
&ff_nut_demuxer,
&ff_nuv_demuxer,
&ff_ogg_demuxer,
&ff_oma_demuxer,
&ff_paf_demuxer,
&ff_pcm_alaw_demuxer,
&ff_pcm_mulaw_demuxer,
&ff_pcm_f64be_demuxer,
&ff_pcm_f64le_demuxer,
&ff_pcm_f32be_demuxer,
&ff_pcm_f32le_demuxer,
&ff_pcm_s32be_demuxer,
&ff_pcm_s32le_demuxer,
&ff_pcm_s24be_demuxer,
&ff_pcm_s24le_demuxer,
&ff_pcm_s16be_demuxer,
&ff_pcm_s16le_demuxer,
&ff_pcm_s8_demuxer,
&ff_pcm_u32be_demuxer,
&ff_pcm_u32le_demuxer,
&ff_pcm_u24be_demuxer,
&ff_pcm_u24le_demuxer,
&ff_pcm_u16be_demuxer,
&ff_pcm_u16le_demuxer,
&ff_pcm_u8_demuxer,
&ff_pjs_demuxer,
&ff_pmp_demuxer,
&ff_pva_demuxer,
&ff_pvf_demuxer,
&ff_qcp_demuxer,
&ff_r3d_demuxer,
&ff_rawvideo_demuxer,
&ff_realtext_demuxer,
&ff_redspark_demuxer,
&ff_rl2_demuxer,
&ff_rm_demuxer,
&ff_roq_demuxer,
&ff_rpl_demuxer,
&ff_rsd_demuxer,
&ff_rso_demuxer,
&ff_rtp_demuxer,
&ff_rtsp_demuxer,
&ff_s337m_demuxer,
&ff_sami_demuxer,
&ff_sap_demuxer,
&ff_sbc_demuxer,
&ff_sbg_demuxer,
&ff_scc_demuxer,
&ff_sdp_demuxer,
&ff_sdr2_demuxer,
&ff_sds_demuxer,
&ff_sdx_demuxer,
&ff_segafilm_demuxer,
&ff_shorten_demuxer,
&ff_siff_demuxer,
&ff_sln_demuxer,
&ff_smacker_demuxer,
&ff_smjpeg_demuxer,
&ff_smush_demuxer,
&ff_sol_demuxer,
&ff_sox_demuxer,
&ff_spdif_demuxer,
&ff_srt_demuxer,
&ff_str_demuxer,
&ff_stl_demuxer,
&ff_subviewer1_demuxer,
&ff_subviewer_demuxer,
&ff_sup_demuxer,
&ff_svag_demuxer,
&ff_swf_demuxer,
&ff_tak_demuxer,
&ff_tedcaptions_demuxer,
&ff_thp_demuxer,
&ff_threedostr_demuxer,
&ff_tiertexseq_demuxer,
&ff_tmv_demuxer,
&ff_truehd_demuxer,
&ff_tta_demuxer,
&ff_txd_demuxer,
&ff_tty_demuxer,
&ff_ty_demuxer,
&ff_v210_demuxer,
&ff_v210x_demuxer,
&ff_vag_demuxer,
&ff_vc1_demuxer,
&ff_vc1t_demuxer,
&ff_vivo_demuxer,
&ff_vmd_demuxer,
&ff_vobsub_demuxer,
&ff_voc_demuxer,
&ff_vpk_demuxer,
&ff_vplayer_demuxer,
&ff_vqf_demuxer,
&ff_w64_demuxer,
&ff_wav_demuxer,
&ff_wc3_demuxer,
&ff_webm_dash_manifest_demuxer,
&ff_webvtt_demuxer,
&ff_wsaud_demuxer,
&ff_wsd_demuxer,
&ff_wsvqa_demuxer,
&ff_wtv_demuxer,
&ff_wve_demuxer,
&ff_wv_demuxer,
&ff_xa_demuxer,
&ff_xbin_demuxer,
&ff_xmv_demuxer,
&ff_xvag_demuxer,
&ff_xwma_demuxer,
&ff_yop_demuxer,
&ff_yuv4mpegpipe_demuxer,
&ff_image_bmp_pipe_demuxer,
&ff_image_dds_pipe_demuxer,
&ff_image_dpx_pipe_demuxer,
&ff_image_exr_pipe_demuxer,
&ff_image_j2k_pipe_demuxer,
&ff_image_jpeg_pipe_demuxer,
&ff_image_jpegls_pipe_demuxer,
&ff_image_pam_pipe_demuxer,
&ff_image_pbm_pipe_demuxer,
&ff_image_pcx_pipe_demuxer,
&ff_image_pgmyuv_pipe_demuxer,
&ff_image_pgm_pipe_demuxer,
&ff_image_pictor_pipe_demuxer,
&ff_image_png_pipe_demuxer,
&ff_image_ppm_pipe_demuxer,
&ff_image_psd_pipe_demuxer,
&ff_image_qdraw_pipe_demuxer,
&ff_image_sgi_pipe_demuxer,
&ff_image_svg_pipe_demuxer,
&ff_image_sunrast_pipe_demuxer,
&ff_image_tiff_pipe_demuxer,
&ff_image_webp_pipe_demuxer,
&ff_image_xpm_pipe_demuxer,
&ff_image_xwd_pipe_demuxer,
NULL };

read_probe实现

一般probe有两种情况。
对于在文件开头存在特征码的封装格式,比如avi、rm/rmvb、flv、mkv、asf可以直接使用特征码。
AVI的特征码是RIFF AVI,下面是FFmpeg中的avi探测函数实现:
//libavformat/avidec.c
static const char avi_headers[][] = {
{ 'R', 'I', 'F', 'F', 'A', 'V', 'I', ' ' },
{ 'R', 'I', 'F', 'F', 'A', 'V', 'I', 'X' },
{ 'R', 'I', 'F', 'F', 'A', 'V', 'I', 0x19 },
{ 'O', 'N', '', ' ', 'O', 'N', '', 'f' },
{ 'R', 'I', 'F', 'F', 'A', 'M', 'V', ' ' },
{ }
};
static int avi_probe(AVProbeData *p)
{
int i; /* check file header */
for (i = ; avi_headers[i][]; i++)
if (AV_RL32(p->buf ) == AV_RL32(avi_headers[i] ) &&
AV_RL32(p->buf + ) == AV_RL32(avi_headers[i] + ))
return AVPROBE_SCORE_MAX; return ;
}

rm/rmvb文件的特征码是.RMF、.ra,下面是FFmpeg中rm探测函数:

//libavformat/rmdec.c
static int rm_probe(AVProbeData *p)
{
/* check file header */
if ((p->buf[] == '.' && p->buf[] == 'R' &&
p->buf[] == 'M' && p->buf[] == 'F' &&
p->buf[] == && p->buf[] == ) ||
(p->buf[] == '.' && p->buf[] == 'r' &&
p->buf[] == 'a' && p->buf[] == 0xfd))
return AVPROBE_SCORE_MAX;
else
return ;
}

flv文件的特征码是FLV,下面是FFmpeg中flv探测函数:

//libavformat/flvdec.c
static int probe(AVProbeData *p, int live)
{
const uint8_t *d = p->buf;
unsigned offset = AV_RB32(d + ); if (d[] == 'F' &&
d[] == 'L' &&
d[] == 'V' &&
d[] < && d[] == &&
offset + < p->buf_size &&
offset > ) {
int is_live = !memcmp(d + offset + , "NGINX RTMP", ); if (live == is_live)
return AVPROBE_SCORE_MAX;
}
return ;
} static int flv_probe(AVProbeData *p)
{
return probe(p, );
}

mkv的特征码就是EBML_Header_ID和已知的DocType,下面是FFmpeg的mkv探测函数:

//libavformat/matroskadec.c
/* top-level master-IDs */
#define EBML_ID_HEADER 0x1A45DFA3
static int matroska_probe(AVProbeData *p)
{
uint64_t total = ;
int len_mask = 0x80, size = , n = , i; /* EBML header? */
if (AV_RB32(p->buf) != EBML_ID_HEADER)
return ; /* length of header */
total = p->buf[];
while (size <= && !(total & len_mask)) {
size++;
len_mask >>= ;
}
if (size > )
return ;
total &= (len_mask - );
while (n < size)
total = (total << ) | p->buf[ + n++]; /* Does the probe data contain the whole header? */
if (p->buf_size < + size + total)
return ; /* The header should contain a known document type. For now,
* we don't parse the whole header but simply check for the
* availability of that array of characters inside the header.
* Not fully fool-proof, but good enough. */
for (i = ; i < FF_ARRAY_ELEMS(matroska_doctypes); i++) {
size_t probelen = strlen(matroska_doctypes[i]);
if (total < probelen)
continue;
for (n = + size; n <= + size + total - probelen; n++)
if (!memcmp(p->buf + n, matroska_doctypes[i], probelen))
return AVPROBE_SCORE_MAX;
} // probably valid EBML header but no recognized doctype
return AVPROBE_SCORE_EXTENSION;
}

ASF/WMV文件的特征码就是ASF_HEADER_GUID,下面是FFmpeg中asf探测函数:

//libavformat/asfdec_f.c
const ff_asf_guid ff_asf_header = {
0x30, 0x26, 0xB2, 0x75, 0x8E, 0x66, 0xCF, 0x11, 0xA6, 0xD9, 0x00, 0xAA, 0x00, 0x62, 0xCE, 0x6C
};
static int asf_probe(AVProbeData *pd)
{
/* check file header */
if (!ff_guidcmp(pd->buf, &ff_asf_header))
return AVPROBE_SCORE_MAX;
else
return ;
}

MP4文件是由不同BOX构成的,需要根据box type来探测实际类型,FFmpeg中mp4探测函数(也包括mov,m4a,3gp,3g2)如下:

//libavformat/mov.c
static int mov_probe(AVProbeData *p)
{
int64_t offset;
uint32_t tag;
int score = ;
int moov_offset = -; /* check file header */
offset = ;
for (;;) {
/* ignore invalid offset */
if ((offset + ) > (unsigned int)p->buf_size)
break;
tag = AV_RL32(p->buf + offset + );
switch(tag) {
/* check for obvious tags */
case MKTAG('m','o','o','v'):
moov_offset = offset + ;
case MKTAG('m','d','a','t'):
case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
case MKTAG('f','t','y','p'):
if (AV_RB32(p->buf+offset) < &&
(AV_RB32(p->buf+offset) != ||
offset + > (unsigned int)p->buf_size ||
AV_RB64(p->buf+offset + ) == )) {
score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
} else if (tag == MKTAG('f','t','y','p') &&
( AV_RL32(p->buf + offset + ) == MKTAG('j','p','',' ')
|| AV_RL32(p->buf + offset + ) == MKTAG('j','p','x',' ')
)) {
score = FFMAX(score, );
} else {
score = AVPROBE_SCORE_MAX;
}
offset = FFMAX(, AV_RB32(p->buf+offset)) + offset;
break;
/* those are more common words, so rate then a bit less */
case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
case MKTAG('w','i','d','e'):
case MKTAG('f','r','e','e'):
case MKTAG('j','u','n','k'):
case MKTAG('p','i','c','t'):
score = FFMAX(score, AVPROBE_SCORE_MAX - );
offset = FFMAX(, AV_RB32(p->buf+offset)) + offset;
break;
case MKTAG(0x82,0x82,0x7f,0x7d):
case MKTAG('s','k','i','p'):
case MKTAG('u','u','i','d'):
case MKTAG('p','r','f','l'):
/* if we only find those cause probedata is too small at least rate them */
score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
offset = FFMAX(, AV_RB32(p->buf+offset)) + offset;
break;
default:
offset = FFMAX(, AV_RB32(p->buf+offset)) + offset;
}
}
if(score > AVPROBE_SCORE_MAX - && moov_offset != -) {
/* moov atom in the header - we should make sure that this is not a
* MOV-packed MPEG-PS */
offset = moov_offset; while(offset < (p->buf_size - )){ /* Sufficient space */
/* We found an actual hdlr atom */
if(AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
AV_RL32(p->buf + offset + ) == MKTAG('m','h','l','r') &&
AV_RL32(p->buf + offset + ) == MKTAG('M','P','E','G')){
av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
/* We found a media handler reference atom describing an
* MPEG-PS-in-MOV, return a
* low score to force expanding the probe window until
* mpegps_probe finds what it needs */
return ;
}else
/* Keep looking */
offset+=;
}
} return score;
}

对于像TS这种流媒体格式,通常通过0x47同步字节和pid判断,FFmpeg中ts的探测函数如下:

//libavformat/mpegts.c
static int analyze(const uint8_t *buf, int size, int packet_size,
int probe)
{
int stat[TS_MAX_PACKET_SIZE];
int stat_all = ;
int i;
int best_score = ; memset(stat, , packet_size * sizeof(*stat)); for (i = ; i < size - ; i++) {
if (buf[i] == 0x47) {
int pid = AV_RB16(buf+) & 0x1FFF;
int asc = buf[i + ] & 0x30;
if (!probe || pid == 0x1FFF || asc) {
int x = i % packet_size;
stat[x]++;
stat_all++;
if (stat[x] > best_score) {
best_score = stat[x];
}
}
}
} return best_score - FFMAX(stat_all - *best_score, )/;
}
static int mpegts_probe(AVProbeData *p)
{
const int size = p->buf_size;
int maxscore = ;
int sumscore = ;
int i;
int check_count = size / TS_FEC_PACKET_SIZE;
#define CHECK_COUNT 10
#define CHECK_BLOCK 100 if (!check_count)
return ; for (i = ; i<check_count; i+=CHECK_BLOCK) {
int left = FFMIN(check_count - i, CHECK_BLOCK);
int score = analyze(p->buf + TS_PACKET_SIZE *i, TS_PACKET_SIZE *left, TS_PACKET_SIZE , );
int dvhs_score = analyze(p->buf + TS_DVHS_PACKET_SIZE*i, TS_DVHS_PACKET_SIZE*left, TS_DVHS_PACKET_SIZE, );
int fec_score = analyze(p->buf + TS_FEC_PACKET_SIZE *i, TS_FEC_PACKET_SIZE *left, TS_FEC_PACKET_SIZE , );
score = FFMAX3(score, dvhs_score, fec_score);
sumscore += score;
maxscore = FFMAX(maxscore, score);
} sumscore = sumscore * CHECK_COUNT / check_count;
maxscore = maxscore * CHECK_COUNT / CHECK_BLOCK; ff_dlog(, "TS score: %d %d\n", sumscore, maxscore); if (check_count > CHECK_COUNT && sumscore > ) {
return AVPROBE_SCORE_MAX + sumscore - CHECK_COUNT;
} else if (check_count >= CHECK_COUNT && sumscore > ) {
return AVPROBE_SCORE_MAX/ + sumscore - CHECK_COUNT;
} else if (check_count >= CHECK_COUNT && maxscore > ) {
return AVPROBE_SCORE_MAX/ + sumscore - CHECK_COUNT;
} else if (sumscore > ) {
return ;
} else {
return ;
}
}

参考文章:

https://www.cnblogs.com/tocy/p/media_container_9-probe-utility.html

FFmpeg多媒体文件格式探测的更多相关文章

  1. 多媒体文件格式(一):MP4 格式

    在互联网常见的格式中,跨平台最好的应该就属MP4文件了.因为MP4文件既可以在PC平台的Flashplayer中播放,又可以在移动平台的Android.iOS等平台中进行播放,而且使用系统默认的播放器 ...

  2. 多媒体文件格式分析 MP3文件结构及编解码流程

    多媒体文件格式分析 http://blog.csdn.net/taniya001/article/details/7962864 多媒体文件格式分析 MP3文件结构及编解码流程 http://www. ...

  3. 多媒体文件格式之ASF

    [时间:2016-06] [状态:Open] ASF,全称Advanced Systems Format,是由微软提出的开放封装格式标准.ASF是微软公司Windows Media的核心.这是一种包含 ...

  4. 多媒体文件格式(二):FLV 格式

    在网络的直播与点播场景中,FLV也是一种常见的格式,FLV是Adobe发布的一种可以作为直播也可以作为点播的封装格式,其封装格式非常简单,均以FLVTAG的形式存在,并且每一个TAG都是独立存在的,接 ...

  5. 多媒体文件格式之AVI

    [时间:2016-07] [状态:Open] AVI(Audio Video Interleaved的缩写)是一种RIFF(Resource Interchange File Format的缩写)文件 ...

  6. 多媒体文件格式之RMVB

    [时间:2016-07] [状态:Open] RM/RMVB是Real公司私有的封装格式,常见的后缀形式是rm.ra.rmvb. 通常封装的都是real转悠的编码格式,比如音频中的sipro.cook ...

  7. 多媒体文件格式之FLV

    [时间:2016-07] [状态:Open] FLV是一个相对简单的多媒体格式,仅支持单节目,也就是说每个FLV只能至多一个音频.至多一个视频.FLV(Flash Video)是Adobe的一个免费开 ...

  8. 多媒体文件格式之MKV

    [时间:2016-07] [状态:Open] MKV是一种开源的多媒体封装格式,是Matroska中应用比较多的格式之一.常见的后缀格式是.mkv(视频,包括音频和字幕)..mka(纯音频)..mks ...

  9. 多媒体文件格式之MP4

    [时间:2016-06] [状态:Open] 学习多媒体容器格式的目的 主要是为了回答以下问题: 该容器中数据是如何组织的? 该容器包含哪些编码格式的数据?这些数据是如何存储的? 该容器包含哪些元数据 ...

随机推荐

  1. CSS Div固定在网页顶部、底部、左侧、右侧

    Div固定在网页顶部 .header { width:100%; height:80px; background-color:#FAFAFA; position:fixed; top:; left:; ...

  2. tableview小结-初学者的问题

    初学者的问题主要集中在,下面几个问题: 一.几个函数总是不被调用:例如: - (UIView *)tableView:(UITableView *)tableView viewForHeaderInS ...

  3. windows下PyCharm运行和调试scrapy

    Scrapy是爬虫抓取框架,Pycharm是强大的python的IDE,为了方便使用需要在PyCharm对scrapy程序进行调试 python PyCharm Scrapy scrapy指令其实就是 ...

  4. css 样式常用属性

    一般的一个DIV的CSS设置属性有:margin,padding,width,height,font-size,text-align,background,float,border 附:< cs ...

  5. Mathtype启动失败与Microsoft公式编辑器Equation的问题处理案例

    最近写毕业论文需要使用Mathtype,安装成功后,启动Word,使用Mathtype,出现各种问题. 遇到的问题: 1.弹出“用于创建对象的程序是Equation.您的计算机尚未安装此程序.若要编辑 ...

  6. Spring RESTful之@ModelAttribute

    @ModelAttribute有俩个位置,一个是在方法体中,下面这个demo的用意就是每次controller@RequestMapping方法被调用之前都会走这个方法,并向Model中(@Reque ...

  7. bzoj4557侦查守卫

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4557 树形DP.和“河流”有点像,也有一个类似“承诺”的东西. 就是用 f 表示当前节点向下 ...

  8. python自动发送邮件

    Python 的 smtplib 模块提供了发送电子邮件的功能.测试报告出来后,然后就把报告发送到邮箱. 一.先来看简单的列子 使用QQ邮箱发送邮件,使用的是授权码,需要先到QQ邮箱申请授权码. 邮箱 ...

  9. opencv读取中文路径报错的问题

    ) ## 经验证,不需要再转bgr,myImread的读图结果已经是和imread一样的 return img

  10. Java垃圾回收原理

    无意中在网络上找到了这篇介绍垃圾回收机制的文章,好文!转一下: 垃圾回收器是如何工作的?我现在就简单的介绍一下 首先要明确几点: Java是在堆上为对象分配空间的 垃圾回收器只跟内存有关,什么IO啊, ...