[FFmpeg-cvslog] Reimplement stream probe try #2
Michael Niedermayer
git at videolan.org
Sun Apr 3 18:20:08 CEST 2011
ffmpeg | branch: master | Michael Niedermayer <michaelni at gmx.at> | Fri Mar 4 01:12:17 2011 +0100| [5b56ad03fa3c580e38322c902891a77ecc93686b] | committer: Michael Niedermayer
Reimplement stream probe try #2
Signed-off-by: Michael Niedermayer <michaelni at gmx.at>
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=5b56ad03fa3c580e38322c902891a77ecc93686b
---
libavformat/asfdec.c | 2 +-
libavformat/avformat.h | 15 ++++++++++++++
libavformat/avidec.c | 2 +-
libavformat/mpeg.c | 4 ++-
libavformat/mpegts.c | 4 +-
libavformat/utils.c | 49 ++++++++++++++++++++++++++++++-----------------
6 files changed, 53 insertions(+), 23 deletions(-)
diff --git a/libavformat/asfdec.c b/libavformat/asfdec.c
index 031d482..82cad56 100644
--- a/libavformat/asfdec.c
+++ b/libavformat/asfdec.c
@@ -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) {
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index 7990ce7..59e899d 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -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
@@ -1057,6 +1063,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
* attempt is made. When the maximum probe size is reached, the input format
diff --git a/libavformat/avidec.c b/libavformat/avidec.c
index 9ba1f57..b605c45 100644
--- a/libavformat/avidec.c
+++ b/libavformat/avidec.c
@@ -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;
diff --git a/libavformat/mpeg.c b/libavformat/mpeg.c
index 3903949..e4f774d 100644
--- a/libavformat/mpeg.c
+++ b/libavformat/mpeg.c
@@ -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:
diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
index 803acb3..71e8d73 100644
--- a/libavformat/mpegts.c
+++ b/libavformat/mpegts.c
@@ -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;
diff --git a/libavformat/utils.c b/libavformat/utils.c
index 8b0060f..c19238e 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -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);
More information about the ffmpeg-cvslog
mailing list