Reimplement stream probe try #2

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
Michael Niedermayer 2011-03-04 01:12:17 +01:00
parent 15957b197a
commit 5b56ad03fa
6 changed files with 53 additions and 23 deletions

View File

@ -292,7 +292,7 @@ static int asf_read_stream_properties(AVFormatContext *s, int64_t size)
if (is_dvr_ms_audio) {
// codec_id and codec_tag are unreliable in dvr_ms
// files. Set them later by probing stream.
st->codec->codec_id = CODEC_ID_PROBE;
st->request_probe= 1;
st->codec->codec_tag = 0;
}
if (st->codec->codec_id == CODEC_ID_AAC) {

View File

@ -638,6 +638,12 @@ typedef struct AVStream {
double duration_error[MAX_STD_TIMEBASES];
int64_t codec_info_duration;
} *info;
/**
* flag to indicate that probing is requested
* NOT PART OF PUBLIC API
*/
int request_probe;
} AVStream;
#define AV_PROGRAM_RUNNING 1
@ -1056,6 +1062,15 @@ AVInputFormat *av_probe_input_format(AVProbeData *pd, int is_opened);
*/
AVInputFormat *av_probe_input_format2(AVProbeData *pd, int is_opened, int *score_max);
/**
* Guess the file format.
*
* @param is_opened Whether the file is already opened; determines whether
* demuxers with or without AVFMT_NOFILE are probed.
* @param score_ret The score of the best detection.
*/
AVInputFormat *av_probe_input_format3(AVProbeData *pd, int is_opened, int *score_ret);
/**
* Probe a bytestream to determine the input format. Each time a probe returns
* with a score that is too low, the probe buffer size is increased and another

View File

@ -652,7 +652,7 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
break;
case AVMEDIA_TYPE_SUBTITLE:
st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
st->codec->codec_id = CODEC_ID_PROBE;
st->request_probe= 1;
break;
default:
st->codec->codec_type = AVMEDIA_TYPE_DATA;

View File

@ -421,6 +421,7 @@ static int mpegps_read_packet(AVFormatContext *s,
MpegDemuxContext *m = s->priv_data;
AVStream *st;
int len, startcode, i, es_type;
int request_probe= 0;
enum CodecID codec_id = CODEC_ID_NONE;
enum AVMediaType type;
int64_t pts, dts, dummy_pos; //dummy_pos is needed for the index building to work
@ -479,7 +480,7 @@ static int mpegps_read_packet(AVFormatContext *s,
if(!memcmp(buf, avs_seqh, 4) && (buf[6] != 0 || buf[7] != 1))
codec_id = CODEC_ID_CAVS;
else
codec_id = CODEC_ID_PROBE;
request_probe= 1;
type = AVMEDIA_TYPE_VIDEO;
} else if (startcode >= 0x1c0 && startcode <= 0x1df) {
type = AVMEDIA_TYPE_AUDIO;
@ -534,6 +535,7 @@ static int mpegps_read_packet(AVFormatContext *s,
goto skip;
st->codec->codec_type = type;
st->codec->codec_id = codec_id;
st->request_probe = request_probe;
if (codec_id != CODEC_ID_PCM_S16BE)
st->need_parsing = AVSTREAM_PARSE_FULL;
found:

View File

@ -704,10 +704,10 @@ static int mpegts_push_data(MpegTSFilter *filter,
code != 0x1ff && code != 0x1f2 && /* program_stream_directory, DSMCC_stream */
code != 0x1f8) { /* ITU-T Rec. H.222.1 type E stream */
pes->state = MPEGTS_PESHEADER;
if (pes->st->codec->codec_id == CODEC_ID_NONE) {
if (!pes->st->request_probe) {
av_dlog(pes->stream, "pid=%x stream_type=%x probing\n",
pes->pid, pes->stream_type);
pes->st->codec->codec_id = CODEC_ID_PROBE;
pes->st->request_probe= 1;
}
} else {
pes->state = MPEGTS_PAYLOAD;

View File

@ -367,11 +367,11 @@ int av_filename_number_test(const char *filename)
return filename && (av_get_frame_filename(buf, sizeof(buf), filename, 1)>=0);
}
AVInputFormat *av_probe_input_format2(AVProbeData *pd, int is_opened, int *score_max)
AVInputFormat *av_probe_input_format3(AVProbeData *pd, int is_opened, int *score_ret)
{
AVProbeData lpd = *pd;
AVInputFormat *fmt1 = NULL, *fmt;
int score;
int score, score_max=0;
if (lpd.buf_size > 10 && ff_id3v2_match(lpd.buf, ID3v2_DEFAULT_MAGIC)) {
int id3len = ff_id3v2_tag_len(lpd.buf);
@ -393,21 +393,33 @@ AVInputFormat *av_probe_input_format2(AVProbeData *pd, int is_opened, int *score
score = 50;
}
}
if (score > *score_max) {
*score_max = score;
if (score > score_max) {
score_max = score;
fmt = fmt1;
}else if (score == *score_max)
}else if (score == score_max)
fmt = NULL;
}
*score_ret= score_max;
return fmt;
}
AVInputFormat *av_probe_input_format2(AVProbeData *pd, int is_opened, int *score_max)
{
int score_ret;
AVInputFormat *fmt= av_probe_input_format3(pd, is_opened, &score_ret);
if(score_ret > *score_max){
*score_max= score_ret;
return fmt;
}else
return NULL;
}
AVInputFormat *av_probe_input_format(AVProbeData *pd, int is_opened){
int score=0;
return av_probe_input_format2(pd, is_opened, &score);
}
static int set_codec_from_probe_data(AVFormatContext *s, AVStream *st, AVProbeData *pd, int score)
static int set_codec_from_probe_data(AVFormatContext *s, AVStream *st, AVProbeData *pd)
{
static const struct {
const char *name; enum CodecID id; enum AVMediaType type;
@ -422,7 +434,8 @@ static int set_codec_from_probe_data(AVFormatContext *s, AVStream *st, AVProbeDa
{ "mpegvideo", CODEC_ID_MPEG2VIDEO, AVMEDIA_TYPE_VIDEO },
{ 0 }
};
AVInputFormat *fmt = av_probe_input_format2(pd, 1, &score);
int score;
AVInputFormat *fmt = av_probe_input_format3(pd, 1, &score);
if (fmt) {
int i;
@ -436,7 +449,7 @@ static int set_codec_from_probe_data(AVFormatContext *s, AVStream *st, AVProbeDa
}
}
}
return !!fmt;
return score;
}
/************************************************************/
@ -688,8 +701,7 @@ int av_read_packet(AVFormatContext *s, AVPacket *pkt)
if (pktl) {
*pkt = pktl->pkt;
if(s->streams[pkt->stream_index]->codec->codec_id != CODEC_ID_PROBE ||
!s->streams[pkt->stream_index]->probe_packets){
if(s->streams[pkt->stream_index]->request_probe <= 0){
s->raw_packet_buffer = pktl->next;
s->raw_packet_buffer_remaining_size += pkt->size;
av_free(pktl);
@ -703,7 +715,8 @@ int av_read_packet(AVFormatContext *s, AVPacket *pkt)
if (!pktl || ret == AVERROR(EAGAIN))
return ret;
for (i = 0; i < s->nb_streams; i++)
s->streams[i]->probe_packets = 0;
if(s->streams[i]->request_probe > 0)
s->streams[i]->request_probe = -1;
continue;
}
st= s->streams[pkt->stream_index];
@ -720,14 +733,13 @@ int av_read_packet(AVFormatContext *s, AVPacket *pkt)
break;
}
if(!pktl && (st->codec->codec_id != CODEC_ID_PROBE ||
!st->probe_packets))
if(!pktl && st->request_probe <= 0)
return ret;
add_to_pktbuf(&s->raw_packet_buffer, pkt, &s->raw_packet_buffer_end);
s->raw_packet_buffer_remaining_size -= pkt->size;
if(st->codec->codec_id == CODEC_ID_PROBE && st->probe_packets){
if(st->request_probe>0){
AVProbeData *pd = &st->probe_data;
int end;
av_log(s, AV_LOG_DEBUG, "probing stream %d pp:%d\n", st->index, st->probe_packets);
@ -742,12 +754,13 @@ int av_read_packet(AVFormatContext *s, AVPacket *pkt)
|| st->probe_packets<=0;
if(end || av_log2(pd->buf_size) != av_log2(pd->buf_size - pkt->size)){
set_codec_from_probe_data(s, st, pd, end ? 0 : AVPROBE_SCORE_MAX/4);
if(st->codec->codec_id != CODEC_ID_PROBE || end){
int score= set_codec_from_probe_data(s, st, pd);
if( (st->codec->codec_id != CODEC_ID_NONE && score > AVPROBE_SCORE_MAX/4)
|| end){
pd->buf_size=0;
av_freep(&pd->buf);
st->probe_packets= 0;
if(st->codec->codec_id != CODEC_ID_PROBE){
st->request_probe= -1;
if(st->codec->codec_id != CODEC_ID_NONE){
av_log(s, AV_LOG_DEBUG, "probed stream %d\n", st->index);
}else
av_log(s, AV_LOG_WARNING, "probed stream %d failed\n", st->index);