>>>>>>>>>>>>>>#### uc->filename = (char *) &uc[1];strcpy(uc->filename, filename);
uc->prot = up;
uc->flags = flags;
uc->is_streamed = 0; /* default = not streamed */
uc->max_packet_size = 0; /* default: stream file */
err = up->url_open(uc, filename, flags);
if (err < 0) {
av_free(uc);
*puc = NULL;
return err;
}
//We must be carefull here as url_seek() could be slow, for example for
//http
if( (flags & (URL_WRONLY | URL_RDWR))
|| !strcmp(up->name, "file"))
if(!uc->is_streamed && url_seek(uc, 0, SEEK_SET) < 0)
uc->is_streamed= 1;
*puc = uc;
return 0;
fail:
*puc = NULL;
return err;
}
上面这个函数不难理解,但有些地方颇值得玩味,比如,上面给出问号的地方,你明白为什么这样Coding么:)很显然,此时up->url_open()实际上调用的是file_open()[libavformat/file.c],看完这个函数,对上面的内存分配,是否恍然大悟:) 上面只是分析了url_open(),还没有分析url_fdopen(s, h);这部分代码,也留给有好奇心的你了:)恩,为了追踪这个流程,走得有些远,但不是全然无用:)
终于来到了【4】,我们来看MPEG TS格式的侦测过程,这其实才是我们今天的主角4. MPEG TS格式的探测过程
[liavformat/mpegts.c]
static int mpegts_probe(A VProbeData *p)
{
#if 1
const int size= p->buf_size;
int score, fec_score, dvhs_score;
#define CHECK_COUNT 10
if (size < (TS_FEC_PACKET_SIZE * CHECK_COUNT))
return -1;
score = analyze(p->buf, TS_PACKET_SIZE *CHECK_COUNT, TS_PACKET_SIZE, NULL);
dvhs_score = analyze(p->buf, TS_DVHS_PACKET_SIZE *CHECK_COUNT, TS_DVHS_PACKET_SIZE, NULL);
fec_score= analyze(p->buf, TS_FEC_PACKET_SIZE*CHECK_COUNT, TS_FEC_PACKET_SIZE, NULL);
// av_log(NULL, A V_LOG_DEBUG, "score: %d, dvhs_score: %d, fec_score: %d \n", score, dvhs_score, fec_score);
// we need a clear definition for the returned score otherwise things will become messy sooner or later
if (score > fec_score && score > dvhs_score && score > 6) return A VPROBE_SCORE_MAX + score - CHECK_COUNT;
浮动油封else if(dvhs_score > score && dvhs_score > fec_score && dvhs_score > 6) return AVPROBE_SCORE_MAX + dvhs_score - CHECK_COUNT;
else if( fec_score > 6) return A VPROBE_SCORE_MAX + fec_score - CHECK_COUNT;
else return -1;
#else
/* only use the extension for safer guess */
if (match_ext(p->filename, "ts"))
return A VPROBE_SCORE_MAX;
else
return 0;
#endif
}
之所以会出现3种格式,主要原因是:TS标准是188Bytes,而小日本自己又弄了一个192Bytes的DVH-S格式,第三种的204Bytes则是在188Bytes的基础上,加上16Bytes的FEC(前向纠错).
static int analyze(const uint8_t *buf, int size, int packet_size, int *index)
{
int stat[packet_size];
int i;
int x=0;
int best_score=0;
memset(stat, 0, packet_size*sizeof(int));
>>>>>>>>>>>>>>####由于查的特定格式至少3个Bytes,因此,至少最后3个Bytes不用查
>>>>>>>>>>>>>>####for(x=i=0; i<size-3; i++){
>>>>>>>>>>>>>>参看后面的协议说明
>>>>>>>>>>>>>>
if(buf[i] == 0x47 && !(buf[i+1] & 0x80) && (buf[i+3] & 0x30)){
stat[x]++;
if(stat[x] > best_score){
best_score= stat[x];
if(index) *index= x;
}
}
x++;
if(x == packet_size) x= 0;