diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2011-07-11 04:23:25 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2011-07-11 04:23:25 +0200 |
commit | 3602ad7ee6fe5caa402e61aa04ac695e1c46fe5e (patch) | |
tree | 5d89faee8784c9f755974a0822a3e9e90673494e /libavformat | |
parent | 3b2d285afbd6304505a96b71877cdfda13f4565c (diff) | |
parent | 142e76f1055de5dde44696e71a5f63f2cb11dedf (diff) | |
download | ffmpeg-streaming-3602ad7ee6fe5caa402e61aa04ac695e1c46fe5e.zip ffmpeg-streaming-3602ad7ee6fe5caa402e61aa04ac695e1c46fe5e.tar.gz |
Merge commit '142e76f1055de5dde44696e71a5f63f2cb11dedf'
* commit '142e76f1055de5dde44696e71a5f63f2cb11dedf':
swscale: fix crash with dithering due incorrect offset calculation.
matroskadec: fix stupid typo (!= -> ==)
build: remove duplicates from order-only directory prerequisite list
build: rework rules for things in the tools dir
configure: fix --cpu=host with gcc 4.6
ARM: use const macro to define constant data in asm
bitdepth: simplify FUNC/FUNCC macros
dsputil: remove ff_emulated_edge_mc macro used in one place
9/10-bit: simplify clipping macros
matroskadec: reindent
matroskadec: defer parsing of cues element until we seek.
lavc: add support for codec-specific defaults.
lavc: make avcodec_alloc_context3 officially public.
lavc: remove a half-working attempt at different defaults for audio/video codecs.
ac3dec: add a drc_scale private option
lavf: add avformat_find_stream_info()
lavc: introduce avcodec_open2() as a replacement for avcodec_open().
Conflicts:
Makefile
libavcodec/utils.c
libavformat/avformat.h
libswscale/swscale_internal.h
Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavformat')
-rw-r--r-- | libavformat/Makefile | 1 | ||||
-rw-r--r-- | libavformat/avformat.h | 27 | ||||
-rw-r--r-- | libavformat/matroskadec.c | 153 | ||||
-rw-r--r-- | libavformat/movenc.c | 2 | ||||
-rw-r--r-- | libavformat/movenchint.c | 2 | ||||
-rw-r--r-- | libavformat/utils.c | 20 |
6 files changed, 141 insertions, 64 deletions
diff --git a/libavformat/Makefile b/libavformat/Makefile index 6d7a342..ce4891b 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -342,5 +342,6 @@ OBJS-$(CONFIG_ALSA_INDEV) += timefilter.o OBJS-$(CONFIG_JACK_INDEV) += timefilter.o TESTPROGS = timefilter +TOOLS = pktdumper probetest include $(SRC_PATH)/subdir.mak diff --git a/libavformat/avformat.h b/libavformat/avformat.h index 3d57fa9..a0c2047 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -1167,6 +1167,7 @@ AVFormatContext *avformat_alloc_output_context(const char *format, int avformat_alloc_output_context2(AVFormatContext **ctx, AVOutputFormat *oformat, const char *format_name, const char *filename); +#if FF_API_FORMAT_PARAMETERS /** * Read packets of a media file to get stream information. This * is useful for file formats with no headers such as MPEG. This @@ -1179,8 +1180,34 @@ int avformat_alloc_output_context2(AVFormatContext **ctx, AVOutputFormat *oforma * @return >=0 if OK, AVERROR_xxx on error * @todo Let the user decide somehow what information is needed so that * we do not waste time getting stuff the user does not need. + * + * @deprecated use avformat_find_stream_info. */ int av_find_stream_info(AVFormatContext *ic); +#endif + +/** + * Read packets of a media file to get stream information. This + * is useful for file formats with no headers such as MPEG. This + * function also computes the real framerate in case of MPEG-2 repeat + * frame mode. + * The logical file position is not changed by this function; + * examined packets may be buffered for later processing. + * + * @param ic media file handle + * @param options If non-NULL, an ic.nb_streams long array of pointers to + * dictionaries, where i-th member contains options for + * codec corresponding to i-th stream. + * On return each dictionary will be filled with options that were not found. + * @return >=0 if OK, AVERROR_xxx on error + * + * @note this function isn't guaranteed to open all the codecs, so + * options being non-empty at return is a perfectly normal behavior. + * + * @todo Let the user decide somehow what information is needed so that + * we do not waste time getting stuff the user does not need. + */ +int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options); /** * Find the "best" stream in the file. diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index f3d7a2d..e89cc83 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -255,6 +255,9 @@ typedef struct { /* What to skip before effectively reading a packet. */ int skip_to_keyframe; uint64_t skip_to_timecode; + + /* File has a CUES element, but we defer parsing until it is needed. */ + int cues_parsing_deferred; } MatroskaDemuxContext; typedef struct { @@ -1139,7 +1142,7 @@ static void matroska_convert_tags(AVFormatContext *s) } } -static void matroska_execute_seekhead(MatroskaDemuxContext *matroska) +static int matroska_parse_seekhead_entry(MatroskaDemuxContext *matroska, int idx) { EbmlList *seekhead_list = &matroska->seekhead; MatroskaSeekhead *seekhead = seekhead_list->elem; @@ -1147,6 +1150,54 @@ static void matroska_execute_seekhead(MatroskaDemuxContext *matroska) int64_t before_pos = avio_tell(matroska->ctx->pb); uint32_t saved_id = matroska->current_id; MatroskaLevel level; + int64_t offset; + int ret = 0; + + if (idx >= seekhead_list->nb_elem + || seekhead[idx].id == MATROSKA_ID_SEEKHEAD + || seekhead[idx].id == MATROSKA_ID_CLUSTER) + return 0; + + /* seek */ + offset = seekhead[idx].pos + matroska->segment_start; + if (avio_seek(matroska->ctx->pb, offset, SEEK_SET) == offset) { + /* We don't want to lose our seekhead level, so we add + * a dummy. This is a crude hack. */ + if (matroska->num_levels == EBML_MAX_DEPTH) { + av_log(matroska->ctx, AV_LOG_INFO, + "Max EBML element depth (%d) reached, " + "cannot parse further.\n", EBML_MAX_DEPTH); + ret = AVERROR_INVALIDDATA; + } else { + level.start = 0; + level.length = (uint64_t)-1; + matroska->levels[matroska->num_levels] = level; + matroska->num_levels++; + matroska->current_id = 0; + + ebml_parse(matroska, matroska_segment, matroska); + + /* remove dummy level */ + while (matroska->num_levels) { + uint64_t length = matroska->levels[--matroska->num_levels].length; + if (length == (uint64_t)-1) + break; + } + } + } + /* seek back */ + avio_seek(matroska->ctx->pb, before_pos, SEEK_SET); + matroska->level_up = level_up; + matroska->current_id = saved_id; + + return ret; +} + +static void matroska_execute_seekhead(MatroskaDemuxContext *matroska) +{ + EbmlList *seekhead_list = &matroska->seekhead; + MatroskaSeekhead *seekhead = seekhead_list->elem; + int64_t before_pos = avio_tell(matroska->ctx->pb); int i; // we should not do any seeking in the streaming case @@ -1154,47 +1205,55 @@ static void matroska_execute_seekhead(MatroskaDemuxContext *matroska) (matroska->ctx->flags & AVFMT_FLAG_IGNIDX)) return; - for (i=0; i<seekhead_list->nb_elem; i++) { - int64_t offset = seekhead[i].pos + matroska->segment_start; - - if (seekhead[i].pos <= before_pos - || seekhead[i].id == MATROSKA_ID_SEEKHEAD - || seekhead[i].id == MATROSKA_ID_CLUSTER) + for (i = 0; i < seekhead_list->nb_elem; i++) { + if (seekhead[i].pos <= before_pos) continue; - /* seek */ - if (avio_seek(matroska->ctx->pb, offset, SEEK_SET) != offset) + // defer cues parsing until we actually need cue data. + if (seekhead[i].id == MATROSKA_ID_CUES) { + matroska->cues_parsing_deferred = 1; continue; + } - /* We don't want to lose our seekhead level, so we add - * a dummy. This is a crude hack. */ - if (matroska->num_levels == EBML_MAX_DEPTH) { - av_log(matroska->ctx, AV_LOG_INFO, - "Max EBML element depth (%d) reached, " - "cannot parse further.\n", EBML_MAX_DEPTH); + if (matroska_parse_seekhead_entry(matroska, i) < 0) break; - } + } +} - level.start = 0; - level.length = (uint64_t)-1; - matroska->levels[matroska->num_levels] = level; - matroska->num_levels++; - matroska->current_id = 0; +static void matroska_parse_cues(MatroskaDemuxContext *matroska) { + EbmlList *seekhead_list = &matroska->seekhead; + MatroskaSeekhead *seekhead = seekhead_list->elem; + EbmlList *index_list; + MatroskaIndex *index; + int index_scale = 1; + int i, j; - ebml_parse(matroska, matroska_segment, matroska); + for (i = 0; i < seekhead_list->nb_elem; i++) + if (seekhead[i].id == MATROSKA_ID_CUES) + break; + assert(i <= seekhead_list->nb_elem); - /* remove dummy level */ - while (matroska->num_levels) { - uint64_t length = matroska->levels[--matroska->num_levels].length; - if (length == (uint64_t)-1) - break; + matroska_parse_seekhead_entry(matroska, i); + + index_list = &matroska->index; + index = index_list->elem; + if (index_list->nb_elem + && index[0].time > 1E14/matroska->time_scale) { + av_log(matroska->ctx, AV_LOG_WARNING, "Working around broken index.\n"); + index_scale = matroska->time_scale; + } + for (i = 0; i < index_list->nb_elem; i++) { + EbmlList *pos_list = &index[i].pos; + MatroskaIndexPos *pos = pos_list->elem; + for (j = 0; j < pos_list->nb_elem; j++) { + MatroskaTrack *track = matroska_find_track_by_num(matroska, pos[j].track); + if (track && track->stream) + av_add_index_entry(track->stream, + pos[j].pos + matroska->segment_start, + index[i].time/index_scale, 0, 0, + AVINDEX_KEYFRAME); } } - - /* seek back */ - avio_seek(matroska->ctx->pb, before_pos, SEEK_SET); - matroska->level_up = level_up; - matroska->current_id = saved_id; } static int matroska_aac_profile(char *codec_id) @@ -1226,9 +1285,6 @@ static int matroska_read_header(AVFormatContext *s, AVFormatParameters *ap) EbmlList *chapters_list = &matroska->chapters; MatroskaChapter *chapters; MatroskaTrack *tracks; - EbmlList *index_list; - MatroskaIndex *index; - int index_scale = 1; uint64_t max_start = 0; Ebml ebml = { 0 }; AVStream *st; @@ -1587,27 +1643,6 @@ static int matroska_read_header(AVFormatContext *s, AVFormatParameters *ap) max_start = chapters[i].start; } - index_list = &matroska->index; - index = index_list->elem; - if (index_list->nb_elem - && index[0].time > 100000000000000/matroska->time_scale) { - av_log(matroska->ctx, AV_LOG_WARNING, "Working around broken index.\n"); - index_scale = matroska->time_scale; - } - for (i=0; i<index_list->nb_elem; i++) { - EbmlList *pos_list = &index[i].pos; - MatroskaIndexPos *pos = pos_list->elem; - for (j=0; j<pos_list->nb_elem; j++) { - MatroskaTrack *track = matroska_find_track_by_num(matroska, - pos[j].track); - if (track && track->stream) - av_add_index_entry(track->stream, - pos[j].pos + matroska->segment_start, - index[i].time/index_scale, 0, 0, - AVINDEX_KEYFRAME); - } - } - matroska_convert_tags(s); return 0; @@ -1954,6 +1989,12 @@ static int matroska_read_seek(AVFormatContext *s, int stream_index, AVStream *st = s->streams[stream_index]; int i, index, index_sub, index_min; + /* Parse the CUES now since we need the index data to seek. */ + if (matroska->cues_parsing_deferred) { + matroska_parse_cues(matroska); + matroska->cues_parsing_deferred = 0; + } + if (!st->nb_index_entries) return 0; timestamp = FFMAX(timestamp, st->index_entries[0].timestamp); diff --git a/libavformat/movenc.c b/libavformat/movenc.c index 21a82b5..b0cdcbc 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -2115,7 +2115,7 @@ static void mov_create_chapter_track(AVFormatContext *s, int tracknum) track->mode = mov->mode; track->tag = MKTAG('t','e','x','t'); track->timescale = MOV_TIMESCALE; - track->enc = avcodec_alloc_context(); + track->enc = avcodec_alloc_context3(NULL); track->enc->codec_type = AVMEDIA_TYPE_SUBTITLE; for (i = 0; i < s->nb_chapters; i++) { diff --git a/libavformat/movenchint.c b/libavformat/movenchint.c index 4e69c73..8e96355 100644 --- a/libavformat/movenchint.c +++ b/libavformat/movenchint.c @@ -36,7 +36,7 @@ int ff_mov_init_hinting(AVFormatContext *s, int index, int src_index) track->tag = MKTAG('r','t','p',' '); track->src_track = src_index; - track->enc = avcodec_alloc_context(); + track->enc = avcodec_alloc_context3(NULL); if (!track->enc) goto fail; track->enc->codec_type = AVMEDIA_TYPE_DATA; diff --git a/libavformat/utils.c b/libavformat/utils.c index 58b1f56..654bc8a 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -2113,7 +2113,7 @@ static int has_decode_delay_been_guessed(AVStream *st) st->codec_info_nb_frames >= 6 + st->codec->has_b_frames; } -static int try_decode_frame(AVStream *st, AVPacket *avpkt) +static int try_decode_frame(AVStream *st, AVPacket *avpkt, AVDictionary **options) { int16_t *samples; AVCodec *codec; @@ -2124,7 +2124,7 @@ static int try_decode_frame(AVStream *st, AVPacket *avpkt) codec = avcodec_find_decoder(st->codec->codec_id); if (!codec) return -1; - ret = avcodec_open(st->codec, codec); + ret = avcodec_open2(st->codec, codec, options); if (ret < 0) return ret; } @@ -2243,12 +2243,20 @@ static int tb_unreliable(AVCodecContext *c){ return 0; } +#if FF_API_FORMAT_PARAMETERS int av_find_stream_info(AVFormatContext *ic) { + return avformat_find_stream_info(ic, NULL); +} +#endif + +int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) +{ int i, count, ret, read_size, j; AVStream *st; AVPacket pkt1, *pkt; int64_t old_offset = avio_tell(ic->pb); + int orig_nb_streams = ic->nb_streams; // new streams might appear, no options for those for(i=0;i<ic->nb_streams;i++) { AVCodec *codec; @@ -2274,12 +2282,12 @@ int av_find_stream_info(AVFormatContext *ic) /* Ensure that subtitle_header is properly set. */ if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE && codec && !st->codec->codec) - avcodec_open(st->codec, codec); + avcodec_open2(st->codec, codec, options ? &options[i] : NULL); //try to just open decoders, in case this is enough to get parameters if(!has_codec_parameters(st->codec)){ if (codec && !st->codec->codec) - avcodec_open(st->codec, codec); + avcodec_open2(st->codec, codec, options ? &options[i] : NULL); } } @@ -2423,7 +2431,7 @@ int av_find_stream_info(AVFormatContext *ic) !has_decode_delay_been_guessed(st) || (st->codec->codec && st->codec->codec->capabilities & CODEC_CAP_CHANNEL_CONF)) - try_decode_frame(st, pkt); + try_decode_frame(st, pkt, (options && i <= orig_nb_streams )? &options[i] : NULL); st->codec_info_nb_frames++; count++; @@ -2703,7 +2711,7 @@ AVStream *av_new_stream(AVFormatContext *s, int id) return NULL; } - st->codec= avcodec_alloc_context(); + st->codec = avcodec_alloc_context3(NULL); if (s->iformat) { /* no default bitrate if decoding */ st->codec->bit_rate = 0; |