Commit 5b56ad03 authored by Michael Niedermayer's avatar Michael Niedermayer

Reimplement stream probe try #2

Signed-off-by: 's avatarMichael Niedermayer <michaelni@gmx.at>
parent 15957b19
...@@ -292,7 +292,7 @@ static int asf_read_stream_properties(AVFormatContext *s, int64_t size) ...@@ -292,7 +292,7 @@ static int asf_read_stream_properties(AVFormatContext *s, int64_t size)
if (is_dvr_ms_audio) { if (is_dvr_ms_audio) {
// codec_id and codec_tag are unreliable in dvr_ms // codec_id and codec_tag are unreliable in dvr_ms
// files. Set them later by probing stream. // files. Set them later by probing stream.
st->codec->codec_id = CODEC_ID_PROBE; st->request_probe= 1;
st->codec->codec_tag = 0; st->codec->codec_tag = 0;
} }
if (st->codec->codec_id == CODEC_ID_AAC) { if (st->codec->codec_id == CODEC_ID_AAC) {
......
...@@ -638,6 +638,12 @@ typedef struct AVStream { ...@@ -638,6 +638,12 @@ typedef struct AVStream {
double duration_error[MAX_STD_TIMEBASES]; double duration_error[MAX_STD_TIMEBASES];
int64_t codec_info_duration; int64_t codec_info_duration;
} *info; } *info;
/**
* flag to indicate that probing is requested
* NOT PART OF PUBLIC API
*/
int request_probe;
} AVStream; } AVStream;
#define AV_PROGRAM_RUNNING 1 #define AV_PROGRAM_RUNNING 1
...@@ -1056,6 +1062,15 @@ AVInputFormat *av_probe_input_format(AVProbeData *pd, int is_opened); ...@@ -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); 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 * 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 * with a score that is too low, the probe buffer size is increased and another
......
...@@ -652,7 +652,7 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap) ...@@ -652,7 +652,7 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
break; break;
case AVMEDIA_TYPE_SUBTITLE: case AVMEDIA_TYPE_SUBTITLE:
st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE; st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
st->codec->codec_id = CODEC_ID_PROBE; st->request_probe= 1;
break; break;
default: default:
st->codec->codec_type = AVMEDIA_TYPE_DATA; st->codec->codec_type = AVMEDIA_TYPE_DATA;
......
...@@ -421,6 +421,7 @@ static int mpegps_read_packet(AVFormatContext *s, ...@@ -421,6 +421,7 @@ static int mpegps_read_packet(AVFormatContext *s,
MpegDemuxContext *m = s->priv_data; MpegDemuxContext *m = s->priv_data;
AVStream *st; AVStream *st;
int len, startcode, i, es_type; int len, startcode, i, es_type;
int request_probe= 0;
enum CodecID codec_id = CODEC_ID_NONE; enum CodecID codec_id = CODEC_ID_NONE;
enum AVMediaType type; enum AVMediaType type;
int64_t pts, dts, dummy_pos; //dummy_pos is needed for the index building to work 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, ...@@ -479,7 +480,7 @@ static int mpegps_read_packet(AVFormatContext *s,
if(!memcmp(buf, avs_seqh, 4) && (buf[6] != 0 || buf[7] != 1)) if(!memcmp(buf, avs_seqh, 4) && (buf[6] != 0 || buf[7] != 1))
codec_id = CODEC_ID_CAVS; codec_id = CODEC_ID_CAVS;
else else
codec_id = CODEC_ID_PROBE; request_probe= 1;
type = AVMEDIA_TYPE_VIDEO; type = AVMEDIA_TYPE_VIDEO;
} else if (startcode >= 0x1c0 && startcode <= 0x1df) { } else if (startcode >= 0x1c0 && startcode <= 0x1df) {
type = AVMEDIA_TYPE_AUDIO; type = AVMEDIA_TYPE_AUDIO;
...@@ -534,6 +535,7 @@ static int mpegps_read_packet(AVFormatContext *s, ...@@ -534,6 +535,7 @@ static int mpegps_read_packet(AVFormatContext *s,
goto skip; goto skip;
st->codec->codec_type = type; st->codec->codec_type = type;
st->codec->codec_id = codec_id; st->codec->codec_id = codec_id;
st->request_probe = request_probe;
if (codec_id != CODEC_ID_PCM_S16BE) if (codec_id != CODEC_ID_PCM_S16BE)
st->need_parsing = AVSTREAM_PARSE_FULL; st->need_parsing = AVSTREAM_PARSE_FULL;
found: found:
......
...@@ -704,10 +704,10 @@ static int mpegts_push_data(MpegTSFilter *filter, ...@@ -704,10 +704,10 @@ static int mpegts_push_data(MpegTSFilter *filter,
code != 0x1ff && code != 0x1f2 && /* program_stream_directory, DSMCC_stream */ code != 0x1ff && code != 0x1f2 && /* program_stream_directory, DSMCC_stream */
code != 0x1f8) { /* ITU-T Rec. H.222.1 type E stream */ code != 0x1f8) { /* ITU-T Rec. H.222.1 type E stream */
pes->state = MPEGTS_PESHEADER; 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", av_dlog(pes->stream, "pid=%x stream_type=%x probing\n",
pes->pid, pes->stream_type); pes->pid, pes->stream_type);
pes->st->codec->codec_id = CODEC_ID_PROBE; pes->st->request_probe= 1;
} }
} else { } else {
pes->state = MPEGTS_PAYLOAD; pes->state = MPEGTS_PAYLOAD;
......
...@@ -367,11 +367,11 @@ int av_filename_number_test(const char *filename) ...@@ -367,11 +367,11 @@ int av_filename_number_test(const char *filename)
return filename && (av_get_frame_filename(buf, sizeof(buf), filename, 1)>=0); 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; AVProbeData lpd = *pd;
AVInputFormat *fmt1 = NULL, *fmt; AVInputFormat *fmt1 = NULL, *fmt;
int score; int score, score_max=0;
if (lpd.buf_size > 10 && ff_id3v2_match(lpd.buf, ID3v2_DEFAULT_MAGIC)) { if (lpd.buf_size > 10 && ff_id3v2_match(lpd.buf, ID3v2_DEFAULT_MAGIC)) {
int id3len = ff_id3v2_tag_len(lpd.buf); int id3len = ff_id3v2_tag_len(lpd.buf);
...@@ -393,21 +393,33 @@ AVInputFormat *av_probe_input_format2(AVProbeData *pd, int is_opened, int *score ...@@ -393,21 +393,33 @@ AVInputFormat *av_probe_input_format2(AVProbeData *pd, int is_opened, int *score
score = 50; score = 50;
} }
} }
if (score > *score_max) { if (score > score_max) {
*score_max = score; score_max = score;
fmt = fmt1; fmt = fmt1;
}else if (score == *score_max) }else if (score == score_max)
fmt = NULL; fmt = NULL;
} }
*score_ret= score_max;
return fmt; 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){ AVInputFormat *av_probe_input_format(AVProbeData *pd, int is_opened){
int score=0; int score=0;
return av_probe_input_format2(pd, is_opened, &score); 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 { static const struct {
const char *name; enum CodecID id; enum AVMediaType type; 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 ...@@ -422,7 +434,8 @@ static int set_codec_from_probe_data(AVFormatContext *s, AVStream *st, AVProbeDa
{ "mpegvideo", CODEC_ID_MPEG2VIDEO, AVMEDIA_TYPE_VIDEO }, { "mpegvideo", CODEC_ID_MPEG2VIDEO, AVMEDIA_TYPE_VIDEO },
{ 0 } { 0 }
}; };
AVInputFormat *fmt = av_probe_input_format2(pd, 1, &score); int score;
AVInputFormat *fmt = av_probe_input_format3(pd, 1, &score);
if (fmt) { if (fmt) {
int i; int i;
...@@ -436,7 +449,7 @@ static int set_codec_from_probe_data(AVFormatContext *s, AVStream *st, AVProbeDa ...@@ -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) ...@@ -688,8 +701,7 @@ int av_read_packet(AVFormatContext *s, AVPacket *pkt)
if (pktl) { if (pktl) {
*pkt = pktl->pkt; *pkt = pktl->pkt;
if(s->streams[pkt->stream_index]->codec->codec_id != CODEC_ID_PROBE || if(s->streams[pkt->stream_index]->request_probe <= 0){
!s->streams[pkt->stream_index]->probe_packets){
s->raw_packet_buffer = pktl->next; s->raw_packet_buffer = pktl->next;
s->raw_packet_buffer_remaining_size += pkt->size; s->raw_packet_buffer_remaining_size += pkt->size;
av_free(pktl); av_free(pktl);
...@@ -703,7 +715,8 @@ int av_read_packet(AVFormatContext *s, AVPacket *pkt) ...@@ -703,7 +715,8 @@ int av_read_packet(AVFormatContext *s, AVPacket *pkt)
if (!pktl || ret == AVERROR(EAGAIN)) if (!pktl || ret == AVERROR(EAGAIN))
return ret; return ret;
for (i = 0; i < s->nb_streams; i++) 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; continue;
} }
st= s->streams[pkt->stream_index]; st= s->streams[pkt->stream_index];
...@@ -720,14 +733,13 @@ int av_read_packet(AVFormatContext *s, AVPacket *pkt) ...@@ -720,14 +733,13 @@ int av_read_packet(AVFormatContext *s, AVPacket *pkt)
break; break;
} }
if(!pktl && (st->codec->codec_id != CODEC_ID_PROBE || if(!pktl && st->request_probe <= 0)
!st->probe_packets))
return ret; return ret;
add_to_pktbuf(&s->raw_packet_buffer, pkt, &s->raw_packet_buffer_end); add_to_pktbuf(&s->raw_packet_buffer, pkt, &s->raw_packet_buffer_end);
s->raw_packet_buffer_remaining_size -= pkt->size; 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; AVProbeData *pd = &st->probe_data;
int end; int end;
av_log(s, AV_LOG_DEBUG, "probing stream %d pp:%d\n", st->index, st->probe_packets); 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) ...@@ -742,12 +754,13 @@ int av_read_packet(AVFormatContext *s, AVPacket *pkt)
|| st->probe_packets<=0; || st->probe_packets<=0;
if(end || av_log2(pd->buf_size) != av_log2(pd->buf_size - pkt->size)){ 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); int score= set_codec_from_probe_data(s, st, pd);
if(st->codec->codec_id != CODEC_ID_PROBE || end){ if( (st->codec->codec_id != CODEC_ID_NONE && score > AVPROBE_SCORE_MAX/4)
|| end){
pd->buf_size=0; pd->buf_size=0;
av_freep(&pd->buf); av_freep(&pd->buf);
st->probe_packets= 0; st->request_probe= -1;
if(st->codec->codec_id != CODEC_ID_PROBE){ if(st->codec->codec_id != CODEC_ID_NONE){
av_log(s, AV_LOG_DEBUG, "probed stream %d\n", st->index); av_log(s, AV_LOG_DEBUG, "probed stream %d\n", st->index);
}else }else
av_log(s, AV_LOG_WARNING, "probed stream %d failed\n", st->index); av_log(s, AV_LOG_WARNING, "probed stream %d failed\n", st->index);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment