From: Michael Niedermayer Date: Thu, 20 Sep 2012 19:46:35 +0000 (+0200) Subject: Merge remote-tracking branch 'qatar/master' X-Git-Tag: android-x86-4.4-r1~9383 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=5864ce13d188260998bbf49a2a774fa9bd445c10;p=android-x86%2Fexternal-ffmpeg.git Merge remote-tracking branch 'qatar/master' * qatar/master: mp3dec: read Xing frame TOC index mp3dec: use named constants for Xing header flags libx264: add support for nal-hrd, required for Blu-ray streams. mov: support random access point grouping matroskadec: properly support BlockDuration Conflicts: libavcodec/libx264.c libavformat/isom.h libavformat/matroskadec.c libavformat/mov.c libavformat/mp3dec.c Merged-by: Michael Niedermayer --- 5864ce13d188260998bbf49a2a774fa9bd445c10 diff --cc libavcodec/libx264.c index 39a7d7db8e,62815ced92..d23ced1c0d --- a/libavcodec/libx264.c +++ b/libavcodec/libx264.c @@@ -457,38 -374,12 +458,42 @@@ static av_cold int X264_init(AVCodecCon if (x4->fastfirstpass) x264_param_apply_fastfirstpass(&x4->params); + /* Allow specifying the x264 profile through AVCodecContext. */ + if (!x4->profile) + switch (avctx->profile) { + case FF_PROFILE_H264_BASELINE: + x4->profile = av_strdup("baseline"); + break; + case FF_PROFILE_H264_HIGH: + x4->profile = av_strdup("high"); + break; + case FF_PROFILE_H264_HIGH_10: + x4->profile = av_strdup("high10"); + break; + case FF_PROFILE_H264_HIGH_422: + x4->profile = av_strdup("high422"); + break; + case FF_PROFILE_H264_HIGH_444: + x4->profile = av_strdup("high444"); + break; + case FF_PROFILE_H264_MAIN: + x4->profile = av_strdup("main"); + break; + default: + break; + } ++ + if (x4->nal_hrd >= 0) + x4->params.i_nal_hrd = x4->nal_hrd; + if (x4->profile) if (x264_param_apply_profile(&x4->params, x4->profile) < 0) { + int i; av_log(avctx, AV_LOG_ERROR, "Error setting profile %s.\n", x4->profile); + av_log(avctx, AV_LOG_INFO, "Possible profiles:"); + for (i = 0; x264_profile_names[i]; i++) + av_log(avctx, AV_LOG_INFO, " %s", x264_profile_names[i]); + av_log(avctx, AV_LOG_INFO, "\n"); return AVERROR(EINVAL); } diff --cc libavformat/isom.h index 6565bdcc17,b191699711..875c3a9fdf --- a/libavformat/isom.h +++ b/libavformat/isom.h @@@ -133,9 -132,9 +138,11 @@@ typedef struct MOVStreamContext uint32_t palette[256]; int has_palette; int64_t data_size; + uint32_t tmcd_flags; ///< tmcd track flags int64_t track_end; ///< used for dts generation in fragmented movie files + int start_pad; ///< amount of samples to skip due to enc-dec delay + unsigned int rap_group_count; + MOVSbgp *rap_group; } MOVStreamContext; typedef struct MOVContext { diff --cc libavformat/matroskadec.c index eb34ef4ee9,0a35a875c1..f4d7071352 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@@ -2175,7 -2021,6 +2175,7 @@@ static int matroska_parse_block(Matrosk st = track->stream; if (st->discard >= AVDISCARD_ALL) return res; - av_assert1(duration != AV_NOPTS_VALUE); ++ av_assert1(block_duration != AV_NOPTS_VALUE); block_time = AV_RB16(data); data += 2; @@@ -2211,20 -2051,22 +2211,21 @@@ if (res) goto end; - if (!duration) - duration = track->default_duration * laces / matroska->time_scale; - if (block_duration != AV_NOPTS_VALUE) { - duration = block_duration / laces; - if (block_duration != duration * laces) { - av_log(matroska->ctx, AV_LOG_WARNING, - "Incorrect block_duration, possibly corrupted container"); - } - } else { - duration = track->default_duration / matroska->time_scale; - block_duration = duration * laces; - } ++ if (!block_duration) ++ block_duration = track->default_duration * laces / matroska->time_scale; - if (timecode != AV_NOPTS_VALUE) + if (cluster_time != (uint64_t)-1 && (block_time >= 0 || cluster_time >= -block_time)) - track->end_timecode = FFMAX(track->end_timecode, timecode+duration); + track->end_timecode = + FFMAX(track->end_timecode, timecode + block_duration); for (n = 0; n < laces; n++) { - int64_t lace_duration = duration*(n+1) / laces - duration*n / laces; ++ int64_t lace_duration = block_duration*(n+1) / laces - block_duration*n / laces; + + if (lace_size[n] > size) { + av_log(matroska->ctx, AV_LOG_ERROR, "Invalid packet size\n"); + break; + } + if ((st->codec->codec_id == AV_CODEC_ID_RA_288 || st->codec->codec_id == AV_CODEC_ID_COOK || st->codec->codec_id == AV_CODEC_ID_SIPR || @@@ -2232,7 -2074,7 +2233,7 @@@ st->codec->block_align && track->audio.sub_packet_size) { res = matroska_parse_rm_audio(matroska, track, st, data, size, -- timecode, duration, pos); ++ timecode, lace_duration, pos); if (res) goto end; diff --cc libavformat/mov.c index c937174ba3,63049f559f..84565c8696 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@@ -1914,7 -1810,10 +1954,10 @@@ static void mov_build_index(MOVContext unsigned int stts_sample = 0; unsigned int sample_size; unsigned int distance = 0; + unsigned int rap_group_index = 0; + unsigned int rap_group_sample = 0; + int rap_group_present = sc->rap_group_count && sc->rap_group; - int key_off = (sc->keyframes && sc->keyframes[0] > 0) || (sc->stps_data && sc->stps_data[0] > 0); + int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_data && sc->stps_data[0] > 0); current_dts -= sc->dts_shift; @@@ -1949,9 -1848,17 +1992,17 @@@ if (stps_index + 1 < sc->stps_count) stps_index++; } + if (rap_group_present && rap_group_index < sc->rap_group_count) { + if (sc->rap_group[rap_group_index].index > 0) + keyframe = 1; + if (++rap_group_sample == sc->rap_group[rap_group_index].count) { + rap_group_sample = 0; + rap_group_index++; + } + } if (keyframe) distance = 0; - sample_size = sc->sample_size > 0 ? sc->sample_size : sc->sample_sizes[current_sample]; + sample_size = sc->alt_sample_size > 0 ? sc->alt_sample_size : sc->sample_sizes[current_sample]; if (sc->pseudo_stream_id == -1 || sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) { AVIndexEntry *e = &st->index_entries[st->nb_index_entries++]; diff --cc libavformat/mp3dec.c index 5bd0e9648b,7d0c2fb6ed..db01cd2081 --- a/libavformat/mp3dec.c +++ b/libavformat/mp3dec.c @@@ -29,12 -29,12 +29,18 @@@ #include "id3v1.h" #include "libavcodec/mpegaudiodecheader.h" + #define XING_FLAG_FRAMES 0x01 + #define XING_FLAG_SIZE 0x02 + #define XING_FLAG_TOC 0x04 + + #define XING_TOC_COUNT 100 + +typedef struct { + int64_t filesize; + int start_pad; + int end_pad; +} MP3Context; + /* mp3 read */ static int mp3_read_probe(AVProbeData *p) @@@ -106,24 -145,13 +134,25 @@@ static int mp3_parse_vbr_tags(AVFormatC v = avio_rb32(s->pb); if(v == MKBETAG('X', 'i', 'n', 'g') || v == MKBETAG('I', 'n', 'f', 'o')) { v = avio_rb32(s->pb); - if(v & 0x1) + if(v & XING_FLAG_FRAMES) frames = avio_rb32(s->pb); - if(v & 0x2) + if(v & XING_FLAG_SIZE) size = avio_rb32(s->pb); - if(v & 4) - avio_skip(s->pb, 100); + if (v & XING_FLAG_TOC && frames) + read_xing_toc(s, size, av_rescale_q(frames, (AVRational){spf, c.sample_rate}, + st->time_base)); + if(v & 8) + avio_skip(s->pb, 4); + + v = avio_rb32(s->pb); + if(v == MKBETAG('L', 'A', 'M', 'E') || v == MKBETAG('L', 'a', 'v', 'f')) { + avio_skip(s->pb, 21-4); + v= avio_rb24(s->pb); + mp3->start_pad = v>>12; + mp3-> end_pad = v&4095; + st->skip_samples = mp3->start_pad + 528 + 1; + av_log(s, AV_LOG_DEBUG, "pad %d %d\n", mp3->start_pad, mp3-> end_pad); + } } /* Check for VBRI tag (always 32 bytes after end of mpegaudio header) */ @@@ -222,14 -233,32 +250,36 @@@ static int mp3_read_packet(AVFormatCont return ret; } - static int read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) + static int mp3_seek(AVFormatContext *s, int stream_index, int64_t timestamp, + int flags) { + MP3Context *mp3 = s->priv_data; - AVStream *st = s->streams[stream_index]; + AVIndexEntry *ie; + AVStream *st = s->streams[0]; + int64_t ret = av_index_search_timestamp(st, timestamp, flags); + uint32_t header = 0; + + if (ret < 0) + return ret; + + ie = &st->index_entries[ret]; + ret = avio_seek(s->pb, ie->pos, SEEK_SET); + if (ret < 0) + return ret; - st->skip_samples = timestamp <= 0 ? mp3->start_pad + 528 + 1 : 0; + while (!s->pb->eof_reached) { + header = (header << 8) + avio_r8(s->pb); + if (ff_mpa_check_header(header) >= 0) { + ff_update_cur_dts(s, st, ie->timestamp); + ret = avio_seek(s->pb, -4, SEEK_CUR); ++ ++ st->skip_samples = ie->timestamp <= 0 ? mp3->start_pad + 528 + 1 : 0; ++ + return (ret >= 0) ? 0 : ret; + } + } - return -1; + return AVERROR_EOF; } AVInputFormat ff_mp3_demuxer = {