From 4df369692ea8aee7094ac0f233cef8d1bee139a3 Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Fri, 2 Mar 2012 10:12:11 -0800 Subject: [PATCH 01/18] mpegts: Do not call read_sl_header() when no bytes remain in the buffer. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org --- libavformat/mpegts.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index b105d8c108..32901a1919 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -889,7 +889,7 @@ static int mpegts_push_data(MpegTSFilter *filter, /* we got the full header. We parse it and get the payload */ pes->state = MPEGTS_PAYLOAD; pes->data_index = 0; - if (pes->stream_type == 0x12) { + if (pes->stream_type == 0x12 && buf_size > 0) { int sl_header_bytes = read_sl_header(pes, &pes->sl, p, buf_size); pes->pes_header_size += sl_header_bytes; p += sl_header_bytes; From 1aa708988ac131cf7d5c8bd59aca256a7c974df9 Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Fri, 2 Mar 2012 10:13:07 -0800 Subject: [PATCH 02/18] mpegts: Pad the packet buffer in handle_packet(). This allows it to be used with get_bits without the thread of overreads. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org --- libavformat/mpegts.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index 32901a1919..fb0c416b3b 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -1772,7 +1772,7 @@ static int read_packet(AVFormatContext *s, uint8_t *buf, int raw_packet_size) static int handle_packets(MpegTSContext *ts, int nb_packets) { AVFormatContext *s = ts->stream; - uint8_t packet[TS_PACKET_SIZE]; + uint8_t packet[TS_PACKET_SIZE+FF_INPUT_BUFFER_PADDING_SIZE]; int packet_num, ret = 0; if (avio_tell(s->pb) != ts->last_pos) { @@ -1794,6 +1794,7 @@ static int handle_packets(MpegTSContext *ts, int nb_packets) ts->stop_parse = 0; packet_num = 0; + memset(packet + TS_PACKET_SIZE, 0, FF_INPUT_BUFFER_PADDING_SIZE); for(;;) { if (ts->stop_parse>0) break; From c179c9e19d3b3a8bb98fcc65d2da1caa293f7919 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 1 Mar 2012 12:25:50 +0100 Subject: [PATCH 03/18] lavc: clarify the meaning of AVCodecContext.frame_number. --- libavcodec/avcodec.h | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 798cac6696..19f114f78d 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -1972,7 +1972,17 @@ typedef struct AVCodecContext { * Samples per packet, initialized when calling 'init'. */ int frame_size; - int frame_number; ///< audio or video frame number + + /** + * Frame counter, set by libavcodec. + * + * - decoding: total number of frames returned from the decoder so far. + * - encoding: total number of frames passed to the encoder so far. + * + * @note the counter is not incremented if encoding/decoding resulted in + * an error. + */ + int frame_number; /** * number of bytes per packet if constant and known or 0 From e42e9b0e4d3eb8b2c9b5e1791344f211b590040c Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Fri, 24 Feb 2012 22:39:19 +0100 Subject: [PATCH 04/18] lavc: preserve avpkt->destruct in ff_alloc_packet(). Also, don't bother with saving/restoring data, av_init_packet doesn't touch it. --- libavcodec/utils.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/libavcodec/utils.c b/libavcodec/utils.c index d797c8a0b7..a91eab1ac1 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -838,14 +838,13 @@ int ff_alloc_packet(AVPacket *avpkt, int size) return AVERROR(EINVAL); if (avpkt->data) { - uint8_t *pkt_data; + void *destruct = avpkt->destruct; if (avpkt->size < size) return AVERROR(EINVAL); - pkt_data = avpkt->data; av_init_packet(avpkt); - avpkt->data = pkt_data; + avpkt->destruct = destruct; avpkt->size = size; return 0; } else { From 7fb6c9225c309c55b85f6974627e26976817bff5 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Fri, 24 Feb 2012 13:14:02 +0100 Subject: [PATCH 05/18] lavc: free the output packet when encoding failed or produced no output. --- libavcodec/avcodec.h | 8 ++++++++ libavcodec/utils.c | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 19f114f78d..3598aaaa85 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -3788,6 +3788,10 @@ int attribute_deprecated avcodec_encode_audio(AVCodecContext *avctx, * avpkt->data is NULL, the encoder will allocate it. * The encoder will set avpkt->size to the size of the * output packet. + * + * If this function fails or produces no output, avpkt will be + * freed using av_free_packet() (i.e. avpkt->destruct will be + * called to free the user supplied buffer). * @param[in] frame AVFrame containing the raw audio data to be encoded. * May be NULL when flushing an encoder that has the * CODEC_CAP_DELAY capability set. @@ -3870,6 +3874,10 @@ int avcodec_encode_video(AVCodecContext *avctx, uint8_t *buf, int buf_size, * The encoder will set avpkt->size to the size of the * output packet. The returned data (if any) belongs to the * caller, he is responsible for freeing it. + * + * If this function fails or produces no output, avpkt will be + * freed using av_free_packet() (i.e. avpkt->destruct will be + * called to free the user supplied buffer). * @param[in] frame AVFrame containing the raw video data to be encoded. * May be NULL when flushing an encoder that has the * CODEC_CAP_DELAY capability set. diff --git a/libavcodec/utils.c b/libavcodec/utils.c index a91eab1ac1..f9927a1383 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -864,6 +864,7 @@ int attribute_align_arg avcodec_encode_audio2(AVCodecContext *avctx, *got_packet_ptr = 0; if (!(avctx->codec->capabilities & CODEC_CAP_DELAY) && !frame) { + av_free_packet(avpkt); av_init_packet(avpkt); avpkt->size = 0; return 0; @@ -962,6 +963,9 @@ int attribute_align_arg avcodec_encode_audio2(AVCodecContext *avctx, if (!ret) avctx->frame_number++; + if (ret < 0 || !*got_packet_ptr) + av_free_packet(avpkt); + /* NOTE: if we add any audio encoders which output non-keyframe packets, this needs to be moved to the encoders, but for now we can do it here to simplify things */ @@ -1095,6 +1099,7 @@ int attribute_align_arg avcodec_encode_video2(AVCodecContext *avctx, *got_packet_ptr = 0; if (!(avctx->codec->capabilities & CODEC_CAP_DELAY) && !frame) { + av_free_packet(avpkt); av_init_packet(avpkt); avpkt->size = 0; return 0; @@ -1121,6 +1126,9 @@ int attribute_align_arg avcodec_encode_video2(AVCodecContext *avctx, avctx->frame_number++; } + if (ret < 0 || !*got_packet_ptr) + av_free_packet(avpkt); + emms_c(); return ret; } From 737ca4482bd68d6dc52a1811f5de8e4952ad7036 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Fri, 24 Feb 2012 18:04:05 -0500 Subject: [PATCH 06/18] vorbisdec: read the previous window flag for long windows When reading sequentially, we are using the actual flag from the previous frame, but when seeking we do not know what the previous window flag was, so we need to read it from the bitstream. --- libavcodec/vorbisdec.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libavcodec/vorbisdec.c b/libavcodec/vorbisdec.c index d3f6faff69..c83d49dbba 100644 --- a/libavcodec/vorbisdec.c +++ b/libavcodec/vorbisdec.c @@ -1510,8 +1510,10 @@ static int vorbis_parse_audio_packet(vorbis_context *vc) blockflag = vc->modes[mode_number].blockflag; blocksize = vc->blocksize[blockflag]; vlen = blocksize / 2; - if (blockflag) - skip_bits(gb, 2); // previous_window, next_window + if (blockflag) { + previous_window = get_bits(gb, 1); + skip_bits1(gb); // next_window + } memset(ch_res_ptr, 0, sizeof(float) * vc->audio_channels * vlen); //FIXME can this be removed ? memset(ch_floor_ptr, 0, sizeof(float) * vc->audio_channels * vlen); //FIXME can this be removed ? From 5602a464c9f9e3c0922f5cfeccaf2fa1c40b2401 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sun, 15 Jan 2012 13:38:03 -0500 Subject: [PATCH 07/18] avcodec: add a Vorbis parser to get packet duration This also allows for removing some of the Vorbis-related hacks. --- libavcodec/Makefile | 1 + libavcodec/allcodecs.c | 1 + libavcodec/version.h | 2 +- libavcodec/vorbis_parser.c | 270 +++++++++++++++++++++++++++++++++++ libavcodec/vorbis_parser.h | 68 +++++++++ libavcodec/vorbisdec.c | 1 - libavformat/oggparsevorbis.c | 1 + libavformat/rtpdec.c | 3 + libavformat/utils.c | 6 +- 9 files changed, 346 insertions(+), 7 deletions(-) create mode 100644 libavcodec/vorbis_parser.c create mode 100644 libavcodec/vorbis_parser.h diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 33a19748eb..e456790f8e 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -644,6 +644,7 @@ OBJS-$(CONFIG_RV40_PARSER) += rv34_parser.o OBJS-$(CONFIG_VC1_PARSER) += vc1_parser.o vc1.o vc1data.o \ msmpeg4.o msmpeg4data.o mpeg4video.o \ h263.o mpegvideo.o error_resilience.o +OBJS-$(CONFIG_VORBIS_PARSER) += vorbis_parser.o xiph.o OBJS-$(CONFIG_VP3_PARSER) += vp3_parser.o OBJS-$(CONFIG_VP8_PARSER) += vp8_parser.o diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index 2844cfcbd7..166f1fd922 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -416,6 +416,7 @@ void avcodec_register_all(void) REGISTER_PARSER (RV30, rv30); REGISTER_PARSER (RV40, rv40); REGISTER_PARSER (VC1, vc1); + REGISTER_PARSER (VORBIS, vorbis); REGISTER_PARSER (VP3, vp3); REGISTER_PARSER (VP8, vp8); diff --git a/libavcodec/version.h b/libavcodec/version.h index 7790f24c0c..f3b40ca511 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -21,7 +21,7 @@ #define AVCODEC_VERSION_H #define LIBAVCODEC_VERSION_MAJOR 54 -#define LIBAVCODEC_VERSION_MINOR 5 +#define LIBAVCODEC_VERSION_MINOR 6 #define LIBAVCODEC_VERSION_MICRO 0 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ diff --git a/libavcodec/vorbis_parser.c b/libavcodec/vorbis_parser.c new file mode 100644 index 0000000000..f8d92e04d0 --- /dev/null +++ b/libavcodec/vorbis_parser.c @@ -0,0 +1,270 @@ +/* + * Copyright (c) 2012 Justin Ruggles + * + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Vorbis audio parser + * + * Determines the duration for each packet. + */ + +#include "get_bits.h" +#include "parser.h" +#include "xiph.h" +#include "vorbis_parser.h" + +static int parse_id_header(AVCodecContext *avctx, VorbisParseContext *s, + const uint8_t *buf, int buf_size) +{ + /* Id header should be 30 bytes */ + if (buf_size < 30) { + av_log(avctx, AV_LOG_ERROR, "Id header is too short\n"); + return AVERROR_INVALIDDATA; + } + + /* make sure this is the Id header */ + if (buf[0] != 1) { + av_log(avctx, AV_LOG_ERROR, "Wrong packet type in Id header\n"); + return AVERROR_INVALIDDATA; + } + + /* check for header signature */ + if (memcmp(&buf[1], "vorbis", 6)) { + av_log(avctx, AV_LOG_ERROR, "Invalid packet signature in Id header\n"); + return AVERROR_INVALIDDATA; + } + + if (!(buf[29] & 0x1)) { + av_log(avctx, AV_LOG_ERROR, "Invalid framing bit in Id header\n"); + return AVERROR_INVALIDDATA; + } + + s->blocksize[0] = 1 << (buf[28] & 0xF); + s->blocksize[1] = 1 << (buf[28] >> 4); + + return 0; +} + +static int parse_setup_header(AVCodecContext *avctx, VorbisParseContext *s, + const uint8_t *buf, int buf_size) +{ + GetBitContext gb, gb0; + uint8_t *rev_buf; + int i, ret = 0; + int got_framing_bit, mode_count, got_mode_header, last_mode_count = 0; + + /* avoid overread */ + if (buf_size < 7) { + av_log(avctx, AV_LOG_ERROR, "Setup header is too short\n"); + return AVERROR_INVALIDDATA; + } + + /* make sure this is the Setup header */ + if (buf[0] != 5) { + av_log(avctx, AV_LOG_ERROR, "Wrong packet type in Setup header\n"); + return AVERROR_INVALIDDATA; + } + + /* check for header signature */ + if (memcmp(&buf[1], "vorbis", 6)) { + av_log(avctx, AV_LOG_ERROR, "Invalid packet signature in Setup header\n"); + return AVERROR_INVALIDDATA; + } + + /* reverse bytes so we can easily read backwards with get_bits() */ + if (!(rev_buf = av_malloc(buf_size))) { + av_log(avctx, AV_LOG_ERROR, "Out of memory\n"); + return AVERROR(ENOMEM); + } + for (i = 0; i < buf_size; i++) + rev_buf[i] = buf[buf_size - 1 - i]; + init_get_bits(&gb, rev_buf, buf_size * 8); + + got_framing_bit = 0; + while (get_bits_left(&gb) > 97) { + if (get_bits1(&gb)) { + got_framing_bit = get_bits_count(&gb); + break; + } + } + if (!got_framing_bit) { + av_log(avctx, AV_LOG_ERROR, "Invalid Setup header\n"); + ret = AVERROR_INVALIDDATA; + goto bad_header; + } + + /* Now we search backwards to find possible valid mode counts. This is not + * fool-proof because we could have false positive matches and read too + * far, but there isn't really any way to be sure without parsing through + * all the many variable-sized fields before the modes. This approach seems + * to work well in testing, and it is similar to how it is handled in + * liboggz. */ + mode_count = 0; + got_mode_header = 0; + while (get_bits_left(&gb) >= 97) { + if (get_bits(&gb, 8) > 63 || get_bits(&gb, 16) || get_bits(&gb, 16)) + break; + skip_bits(&gb, 1); + mode_count++; + if (mode_count > 64) + break; + gb0 = gb; + if (get_bits(&gb0, 6) + 1 == mode_count) { + got_mode_header = 1; + last_mode_count = mode_count; + } + } + if (!got_mode_header) { + av_log(avctx, AV_LOG_ERROR, "Invalid Setup header\n"); + ret = AVERROR_INVALIDDATA; + goto bad_header; + } + /* All samples I've seen use <= 2 modes, so ask for a sample if we find + * more than that, as it is most likely a false positive. If we get any + * we may need to approach this the long way and parse the whole Setup + * header, but I hope very much that it never comes to that. */ + if (last_mode_count > 2) { + av_log_ask_for_sample(avctx, "%d modes found. This is either a false " + "positive or a sample from an unknown encoder.\n", + last_mode_count); + } + /* We're limiting the mode count to 63 so that we know that the previous + * block flag will be in the first packet byte. */ + if (last_mode_count > 63) { + av_log(avctx, AV_LOG_ERROR, "Unsupported mode count: %d\n", + last_mode_count); + ret = AVERROR_INVALIDDATA; + goto bad_header; + } + s->mode_count = mode_count = last_mode_count; + /* Determine the number of bits required to code the mode and turn that + * into a bitmask to directly access the mode from the first frame byte. */ + s->mode_mask = ((1 << (av_log2(mode_count - 1) + 1)) - 1) << 1; + /* The previous window flag is the next bit after the mode */ + s->prev_mask = (s->mode_mask | 0x1) + 1; + + init_get_bits(&gb, rev_buf, buf_size * 8); + skip_bits_long(&gb, got_framing_bit); + for (i = mode_count - 1; i >= 0; i--) { + skip_bits_long(&gb, 40); + s->mode_blocksize[i] = s->blocksize[get_bits1(&gb)]; + } + +bad_header: + av_free(rev_buf); + return ret; +} + +int avpriv_vorbis_parse_extradata(AVCodecContext *avctx, VorbisParseContext *s) +{ + uint8_t *header_start[3]; + int header_len[3]; + int ret; + + s->avctx = avctx; + s->extradata_parsed = 1; + + if ((ret = avpriv_split_xiph_headers(avctx->extradata, + avctx->extradata_size, 30, + header_start, header_len)) < 0) { + av_log(avctx, AV_LOG_ERROR, "Extradata corrupt.\n"); + return ret; + } + + if ((ret = parse_id_header(avctx, s, header_start[0], header_len[0])) < 0) + return ret; + + if ((ret = parse_setup_header(avctx, s, header_start[2], header_len[2])) < 0) + return ret; + + s->valid_extradata = 1; + s->previous_blocksize = s->mode_blocksize[0]; + + return 0; +} + +int avpriv_vorbis_parse_frame(VorbisParseContext *s, const uint8_t *buf, + int buf_size) +{ + int duration = 0; + + if (s->valid_extradata && buf_size > 0) { + int mode, current_blocksize; + int previous_blocksize = s->previous_blocksize; + + if (buf[0] & 1) { + av_log(s->avctx, AV_LOG_ERROR, "Invalid packet\n"); + return AVERROR_INVALIDDATA; + } + if (s->mode_count == 1) + mode = 0; + else + mode = (buf[0] & s->mode_mask) >> 1; + if (mode >= s->mode_count) { + av_log(s->avctx, AV_LOG_ERROR, "Invalid mode in packet\n"); + return AVERROR_INVALIDDATA; + } + if (mode) { + int flag = !!(buf[0] & s->prev_mask); + previous_blocksize = s->blocksize[flag]; + } + current_blocksize = s->mode_blocksize[mode]; + duration = (previous_blocksize + current_blocksize) >> 2; + s->previous_blocksize = current_blocksize; + } + + return duration; +} + +void avpriv_vorbis_parse_reset(VorbisParseContext *s) +{ + if (s->valid_extradata) + s->previous_blocksize = s->mode_blocksize[0]; +} + +#if CONFIG_VORBIS_PARSER +static int vorbis_parse(AVCodecParserContext *s1, AVCodecContext *avctx, + const uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size) +{ + VorbisParseContext *s = s1->priv_data; + int duration; + + if (!s->extradata_parsed && avctx->extradata && avctx->extradata_size) + if (avpriv_vorbis_parse_extradata(avctx, s)) + goto end; + + if ((duration = avpriv_vorbis_parse_frame(s, buf, buf_size)) >= 0) + s1->duration = duration; + +end: + /* always return the full packet. this parser isn't doing any splitting or + combining, only packet analysis */ + *poutbuf = buf; + *poutbuf_size = buf_size; + return buf_size; +} + +AVCodecParser ff_vorbis_parser = { + .codec_ids = { CODEC_ID_VORBIS }, + .priv_data_size = sizeof(VorbisParseContext), + .parser_parse = vorbis_parse, +}; +#endif /* CONFIG_VORBIS_PARSER */ diff --git a/libavcodec/vorbis_parser.h b/libavcodec/vorbis_parser.h new file mode 100644 index 0000000000..480a918f7b --- /dev/null +++ b/libavcodec/vorbis_parser.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2012 Justin Ruggles + * + * This file is part of Libav. + * + * Libav is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * Libav is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Vorbis audio parser + * + * Determines the duration for each packet. + */ + +#ifndef AVCODEC_VORBIS_PARSER_H +#define AVCODEC_VORBIS_PARSER_H + +#include "avcodec.h" + +typedef struct VorbisParseContext { + AVCodecContext *avctx; ///< codec context + int extradata_parsed; ///< we have attempted to parse extradata + int valid_extradata; ///< extradata is valid, so we can calculate duration + int blocksize[2]; ///< short and long window sizes + int previous_blocksize; ///< previous window size + int mode_blocksize[64]; ///< window size mapping for each mode + int mode_count; ///< number of modes + int mode_mask; ///< bitmask used to get the mode in each packet + int prev_mask; ///< bitmask used to get the previous mode flag in each packet +} VorbisParseContext; + +/** + * Initialize the Vorbis parser using headers in the extradata. + * + * @param avctx codec context + * @param s Vorbis parser context + */ +int avpriv_vorbis_parse_extradata(AVCodecContext *avctx, VorbisParseContext *s); + +/** + * Get the duration for a Vorbis packet. + * + * avpriv_vorbis_parse_extradata() must have been successfully called prior to + * this in order for a correct duration to be returned. + * + * @param s Vorbis parser context + * @param buf buffer containing a Vorbis frame + * @param buf_size size of the buffer + */ +int avpriv_vorbis_parse_frame(VorbisParseContext *s, const uint8_t *buf, + int buf_size); + +void avpriv_vorbis_parse_reset(VorbisParseContext *s); + +#endif /* AVCODEC_VORBIS_PARSER_H */ diff --git a/libavcodec/vorbisdec.c b/libavcodec/vorbisdec.c index c83d49dbba..0d491c82dd 100644 --- a/libavcodec/vorbisdec.c +++ b/libavcodec/vorbisdec.c @@ -1031,7 +1031,6 @@ static av_cold int vorbis_decode_init(AVCodecContext *avccontext) avccontext->channels = vc->audio_channels; avccontext->sample_rate = vc->audio_samplerate; - avccontext->frame_size = FFMIN(vc->blocksize[0], vc->blocksize[1]) >> 2; avcodec_get_frame_defaults(&vc->frame); avccontext->coded_frame = &vc->frame; diff --git a/libavformat/oggparsevorbis.c b/libavformat/oggparsevorbis.c index ba9b348456..b9d9f575e0 100644 --- a/libavformat/oggparsevorbis.c +++ b/libavformat/oggparsevorbis.c @@ -251,6 +251,7 @@ vorbis_header (AVFormatContext * s, int idx) st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_id = CODEC_ID_VORBIS; + st->need_parsing = AVSTREAM_PARSE_HEADERS; if (srate > 0) { st->codec->sample_rate = srate; diff --git a/libavformat/rtpdec.c b/libavformat/rtpdec.c index a8c5c3ff4c..61653f7b39 100644 --- a/libavformat/rtpdec.c +++ b/libavformat/rtpdec.c @@ -396,6 +396,9 @@ RTPDemuxContext *ff_rtp_parse_open(AVFormatContext *s1, AVStream *st, URLContext case CODEC_ID_H264: st->need_parsing = AVSTREAM_PARSE_FULL; break; + case CODEC_ID_VORBIS: + st->need_parsing = AVSTREAM_PARSE_HEADERS; + break; case CODEC_ID_ADPCM_G722: /* According to RFC 3551, the stream clock rate is 8000 * even if the sample rate is 16000. */ diff --git a/libavformat/utils.c b/libavformat/utils.c index cf4392b581..123bc8bf9a 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -701,9 +701,6 @@ static int get_audio_frame_size(AVCodecContext *enc, int size) { int frame_size; - if(enc->codec_id == CODEC_ID_VORBIS) - return -1; - if (enc->frame_size <= 1) { int bits_per_sample = av_get_bits_per_sample(enc->codec_id); @@ -1995,8 +1992,7 @@ static int has_codec_parameters(AVCodecContext *avctx) case AVMEDIA_TYPE_AUDIO: val = avctx->sample_rate && avctx->channels && avctx->sample_fmt != AV_SAMPLE_FMT_NONE; if (!avctx->frame_size && - (avctx->codec_id == CODEC_ID_VORBIS || - avctx->codec_id == CODEC_ID_AAC || + (avctx->codec_id == CODEC_ID_AAC || avctx->codec_id == CODEC_ID_MP1 || avctx->codec_id == CODEC_ID_MP2 || avctx->codec_id == CODEC_ID_MP3 || From 5a9b952201e5fde03be619dc59bda10463abeefa Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Wed, 29 Feb 2012 18:08:46 -0500 Subject: [PATCH 08/18] thp: set audio packet durations --- libavformat/thp.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libavformat/thp.c b/libavformat/thp.c index 731f5af968..5a1205eb9a 100644 --- a/libavformat/thp.c +++ b/libavformat/thp.c @@ -181,6 +181,9 @@ static int thp_read_packet(AVFormatContext *s, } pkt->stream_index = thp->audio_stream_index; + if (thp->audiosize >= 8) + pkt->duration = AV_RB32(&pkt->data[4]); + thp->audiosize = 0; thp->frame++; } From 6776a8f189d79c4a3ee6b8a164bb12238d7cbd42 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Tue, 21 Jun 2011 02:49:20 +0200 Subject: [PATCH 09/18] mpegaudio_parser: be less picky about the start position Signed-off-by: Michael Niedermayer Signed-off-by: Justin Ruggles --- libavcodec/mpegaudio_parser.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavcodec/mpegaudio_parser.c b/libavcodec/mpegaudio_parser.c index 5fd9037b53..3748f5d53e 100644 --- a/libavcodec/mpegaudio_parser.c +++ b/libavcodec/mpegaudio_parser.c @@ -66,7 +66,8 @@ static int mpegaudio_parse(AVCodecParserContext *s1, ret = avpriv_mpa_decode_header(avctx, state, &sr, &channels, &frame_size, &bit_rate); if (ret < 4) { - s->header_count= -2; + if (i > 4) + s->header_count = -2; } else { if((state&SAME_HEADER_MASK) != (s->header&SAME_HEADER_MASK) && s->header) s->header_count= -3; From 0b8b7db01b30248430b2dcc29c6e904df47a991e Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Mon, 16 Jan 2012 11:49:51 -0500 Subject: [PATCH 10/18] mpegaudio_parser: do not ignore information from the first parsed frame Update some demuxing and seeking fate tests. --- libavcodec/mpegaudio_parser.c | 2 +- tests/ref/fate/pva-demux | 6 +++--- tests/ref/fate/wtv-demux | 12 ++++++------ tests/ref/seek/mp2_mp2 | 14 +++++--------- 4 files changed, 15 insertions(+), 19 deletions(-) diff --git a/libavcodec/mpegaudio_parser.c b/libavcodec/mpegaudio_parser.c index 3748f5d53e..017d6e1cda 100644 --- a/libavcodec/mpegaudio_parser.c +++ b/libavcodec/mpegaudio_parser.c @@ -75,7 +75,7 @@ static int mpegaudio_parse(AVCodecParserContext *s1, s->header_count++; s->frame_size = ret-4; - if(s->header_count > 1){ + if (s->header_count > 0) { avctx->sample_rate= sr; avctx->channels = channels; s1->duration = frame_size; diff --git a/tests/ref/fate/pva-demux b/tests/ref/fate/pva-demux index 8eb6fc9382..69b1d4015f 100644 --- a/tests/ref/fate/pva-demux +++ b/tests/ref/fate/pva-demux @@ -1,8 +1,8 @@ #tb 0: 1/90000 0, 0, 0, 2160, 384, 0x071abcc8 -0, 0, 0, 2160, 384, 0x31c9aee0 -0, 2160, 2160, 2160, 384, 0xa50eaa94 -0, 4320, 4320, 2160, 384, 0x9e86ba0e +0, 2160, 2160, 2160, 384, 0x31c9aee0 +0, 4320, 4320, 2160, 384, 0xa50eaa94 +0, 6480, 6480, 2160, 384, 0x9e86ba0e 0, 8640, 8640, 2160, 384, 0x2321b800 0, 10800, 10800, 2160, 384, 0x2347afa8 0, 12960, 12960, 2160, 384, 0x0831b8d3 diff --git a/tests/ref/fate/wtv-demux b/tests/ref/fate/wtv-demux index 6174604a35..ae44958005 100644 --- a/tests/ref/fate/wtv-demux +++ b/tests/ref/fate/wtv-demux @@ -1,11 +1,11 @@ #tb 0: 1/10000000 #tb 1: 1/10000000 -1, -2, -2, 180000, 576, 0x9b6e1638 -1, 179998, 179998, 240000, 576, 0x0ca91183 -1, 419998, 419998, 240000, 576, 0xec6a180f -1, 659998, 659998, 240000, 576, 0x478a2b9b -1, 899998, 899998, 240000, 576, 0x00fa15b3 -1, 1139998, 1139998, 240000, 576, 0xfb551816 +1, -2, -2, 240000, 576, 0x9b6e1638 +1, 239998, 239998, 240000, 576, 0x0ca91183 +1, 479998, 479998, 240000, 576, 0xec6a180f +1, 719998, 719998, 240000, 576, 0x478a2b9b +1, 959998, 959998, 240000, 576, 0x00fa15b3 +1, 1199998, 1199998, 240000, 576, 0xfb551816 1, 1439998, 1439998, 240000, 576, 0x422e12bd 1, 1679998, 1679998, 240000, 576, 0xa7581b29 1, 1919998, 1919998, 240000, 576, 0xd4b31a74 diff --git a/tests/ref/seek/mp2_mp2 b/tests/ref/seek/mp2_mp2 index 6166cb380b..8de36761b0 100644 --- a/tests/ref/seek/mp2_mp2 +++ b/tests/ref/seek/mp2_mp2 @@ -1,20 +1,18 @@ ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size: 417 ret: 0 st:-1 flags:0 ts:-1.000000 -ret: 0 st: 0 flags:1 dts: 0.026122 pts: 0.026122 pos: 417 size: 418 +ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size: 417 ret: 0 st:-1 flags:1 ts: 1.894167 ret: 0 st: 0 flags:1 dts: 1.880816 pts: 1.880816 pos: 30093 size: 418 ret: 0 st: 0 flags:0 ts: 0.788334 ret: 0 st: 0 flags:1 dts: 0.809796 pts: 0.809796 pos: 12956 size: 418 -ret: 0 st: 0 flags:1 ts:-0.317499 -ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size: 417 +ret:-1 st: 0 flags:1 ts:-0.317499 ret: 0 st:-1 flags:0 ts: 2.576668 ret: 0 st: 0 flags:1 dts: 2.586122 pts: 2.586122 pos: 41377 size: 418 ret: 0 st:-1 flags:1 ts: 1.470835 ret: 0 st: 0 flags:1 dts: 1.462857 pts: 1.462857 pos: 23405 size: 418 ret: 0 st: 0 flags:0 ts: 0.365002 ret: 0 st: 0 flags:1 dts: 0.365714 pts: 0.365714 pos: 5851 size: 418 -ret: 0 st: 0 flags:1 ts:-0.740831 -ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size: 417 +ret:-1 st: 0 flags:1 ts:-0.740831 ret: 0 st:-1 flags:0 ts: 2.153336 ret: 0 st: 0 flags:1 dts: 2.168163 pts: 2.168163 pos: 34690 size: 418 ret: 0 st:-1 flags:1 ts: 1.047503 @@ -41,13 +39,11 @@ ret: 0 st: 0 flags:1 ts: 1.989173 ret: 0 st: 0 flags:1 dts: 1.985306 pts: 1.985306 pos: 31764 size: 418 ret: 0 st:-1 flags:0 ts: 0.883340 ret: 0 st: 0 flags:1 dts: 0.888163 pts: 0.888163 pos: 14210 size: 418 -ret: 0 st:-1 flags:1 ts:-0.222493 -ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size: 417 +ret:-1 st:-1 flags:1 ts:-0.222493 ret: 0 st: 0 flags:0 ts: 2.671674 ret: 0 st: 0 flags:1 dts: 2.690612 pts: 2.690612 pos: 43049 size: 418 ret: 0 st: 0 flags:1 ts: 1.565841 ret: 0 st: 0 flags:1 dts: 1.541224 pts: 1.541224 pos: 24659 size: 418 ret: 0 st:-1 flags:0 ts: 0.460008 ret: 0 st: 0 flags:1 dts: 0.470204 pts: 0.470204 pos: 7523 size: 418 -ret: 0 st:-1 flags:1 ts:-0.645825 -ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 0 size: 417 +ret:-1 st:-1 flags:1 ts:-0.645825 From 101c369b7cccc6a0c4fcbd4aec26894a5ffc74f7 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Fri, 13 Jan 2012 13:35:06 -0500 Subject: [PATCH 11/18] tta demuxer: set packet duration --- libavformat/tta.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/libavformat/tta.c b/libavformat/tta.c index d7d41172d6..0b2337baf2 100644 --- a/libavformat/tta.c +++ b/libavformat/tta.c @@ -27,6 +27,8 @@ typedef struct { int totalframes, currentframe; + int frame_size; + int last_frame_size; } TTAContext; static int tta_probe(AVProbeData *p) @@ -42,7 +44,7 @@ static int tta_read_header(AVFormatContext *s) { TTAContext *c = s->priv_data; AVStream *st; - int i, channels, bps, samplerate, datalen, framelen; + int i, channels, bps, samplerate, datalen; uint64_t framepos, start_offset; if (!av_dict_get(s->metadata, "", NULL, AV_DICT_IGNORE_SUFFIX)) @@ -69,8 +71,11 @@ static int tta_read_header(AVFormatContext *s) avio_skip(s->pb, 4); // header crc - framelen = samplerate*256/245; - c->totalframes = datalen / framelen + ((datalen % framelen) ? 1 : 0); + c->frame_size = samplerate * 256 / 245; + c->last_frame_size = datalen % c->frame_size; + if (!c->last_frame_size) + c->last_frame_size = c->frame_size; + c->totalframes = datalen / c->frame_size + (c->last_frame_size < c->frame_size); c->currentframe = 0; if(c->totalframes >= UINT_MAX/sizeof(uint32_t)){ @@ -90,7 +95,8 @@ static int tta_read_header(AVFormatContext *s) for (i = 0; i < c->totalframes; i++) { uint32_t size = avio_rl32(s->pb); - av_add_index_entry(st, framepos, i*framelen, size, 0, AVINDEX_KEYFRAME); + av_add_index_entry(st, framepos, i * c->frame_size, size, 0, + AVINDEX_KEYFRAME); framepos += size; } avio_skip(s->pb, 4); // seektable crc @@ -132,6 +138,8 @@ static int tta_read_packet(AVFormatContext *s, AVPacket *pkt) ret = av_get_packet(s->pb, pkt, size); pkt->dts = st->index_entries[c->currentframe++].timestamp; + pkt->duration = c->currentframe == c->totalframes ? c->last_frame_size : + c->frame_size; return ret; } From d0ab58507480dde81c7127f1eea29e10f91eb4b6 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Fri, 13 Jan 2012 14:04:11 -0500 Subject: [PATCH 12/18] vqf: set packet duration Fixes timestamp calculation. The FATE reference is updated because timestamp calculations are now more accurate. Previous timestamps were based on average bit rate. --- libavformat/vqf.c | 3 ++- tests/ref/fate/vqf-demux | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/libavformat/vqf.c b/libavformat/vqf.c index b9fa8be4f3..14085b9a52 100644 --- a/libavformat/vqf.c +++ b/libavformat/vqf.c @@ -201,7 +201,7 @@ static int vqf_read_header(AVFormatContext *s) return -1; } c->frame_bit_len = st->codec->bit_rate*size/st->codec->sample_rate; - avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); + avpriv_set_pts_info(st, 64, size, st->codec->sample_rate); /* put first 12 bytes of COMM chunk in extradata */ if (!(st->codec->extradata = av_malloc(12 + FF_INPUT_BUFFER_PADDING_SIZE))) @@ -225,6 +225,7 @@ static int vqf_read_packet(AVFormatContext *s, AVPacket *pkt) pkt->pos = avio_tell(s->pb); pkt->stream_index = 0; + pkt->duration = 1; pkt->data[0] = 8 - c->remaining_bits; // Number of bits to skip pkt->data[1] = c->last_frame_bits; diff --git a/tests/ref/fate/vqf-demux b/tests/ref/fate/vqf-demux index 3d4cd3dd78..3acae60f5a 100644 --- a/tests/ref/fate/vqf-demux +++ b/tests/ref/fate/vqf-demux @@ -1 +1 @@ -178a10705baabc5b82bd79240f38a700 +d72fb75fb22f4bcc94a1dc7af5356ec1 From 01be6fa926dc3de593756ffd1e09f9523be5fd00 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Wed, 11 Jan 2012 09:41:06 -0500 Subject: [PATCH 13/18] psx-str: fix audio pts Each packet has 18 sectors with 224/channels samples in each sector. --- libavformat/psxstr.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libavformat/psxstr.c b/libavformat/psxstr.c index 61e24e204f..6405c246bd 100644 --- a/libavformat/psxstr.c +++ b/libavformat/psxstr.c @@ -224,7 +224,9 @@ static int str_read_packet(AVFormatContext *s, // st->codec->bit_rate = 0; //FIXME; st->codec->block_align = 128; - avpriv_set_pts_info(st, 64, 128, st->codec->sample_rate); + avpriv_set_pts_info(st, 64, 18 * 224 / st->codec->channels, + st->codec->sample_rate); + st->start_time = 0; } pkt = ret_pkt; if (av_new_packet(pkt, 2304)) @@ -233,6 +235,7 @@ static int str_read_packet(AVFormatContext *s, pkt->stream_index = str->channels[channel].audio_stream_index; + pkt->duration = 1; return 0; default: av_log(s, AV_LOG_WARNING, "Unknown sector type %02X\n", sector[0x12]); From ea289186f04fa8b9f2cc3bc1aba1cb239ab56f47 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Wed, 11 Jan 2012 10:22:47 -0500 Subject: [PATCH 14/18] ea: fix audio pts The time base is 1 / sample_rate, not 90000. Several more codecs encode the sample count in the first 4 bytes of the chunk, so we set the durations accordingly. Also, we can set start_time and packet duration instead of keeping track of the sample count in the demuxer. --- libavformat/electronicarts.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/libavformat/electronicarts.c b/libavformat/electronicarts.c index 6a07dac7e8..47ef40f69d 100644 --- a/libavformat/electronicarts.c +++ b/libavformat/electronicarts.c @@ -70,7 +70,6 @@ typedef struct EaDemuxContext { enum CodecID audio_codec; int audio_stream_index; - int audio_frame_counter; int bytes; int sample_rate; @@ -469,7 +468,7 @@ static int ea_read_header(AVFormatContext *s) st->codec->bits_per_coded_sample / 4; st->codec->block_align = st->codec->channels*st->codec->bits_per_coded_sample; ea->audio_stream_index = st->index; - ea->audio_frame_counter = 0; + st->start_time = 0; } return 1; @@ -513,24 +512,26 @@ static int ea_read_packet(AVFormatContext *s, if (ret < 0) return ret; pkt->stream_index = ea->audio_stream_index; - pkt->pts = 90000; - pkt->pts *= ea->audio_frame_counter; - pkt->pts /= ea->sample_rate; switch (ea->audio_codec) { case CODEC_ID_ADPCM_EA: - /* 2 samples/byte, 1 or 2 samples per frame depending - * on stereo; chunk also has 12-byte header */ - ea->audio_frame_counter += ((chunk_size - 12) * 2) / - ea->num_channels; + case CODEC_ID_ADPCM_EA_R1: + case CODEC_ID_ADPCM_EA_R2: + case CODEC_ID_ADPCM_IMA_EA_EACS: + pkt->duration = AV_RL32(pkt->data); + break; + case CODEC_ID_ADPCM_EA_R3: + pkt->duration = AV_RB32(pkt->data); + break; + case CODEC_ID_ADPCM_IMA_EA_SEAD: + pkt->duration = ret * 2 / ea->num_channels; break; case CODEC_ID_PCM_S16LE_PLANAR: case CODEC_ID_MP3: - ea->audio_frame_counter += num_samples; + pkt->duration = num_samples; break; default: - ea->audio_frame_counter += chunk_size / - (ea->bytes * ea->num_channels); + pkt->duration = chunk_size / (ea->bytes * ea->num_channels); } packet_read = 1; From 4da374f8a9bc7cf790e6f5b30af3a30f0b777348 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Wed, 11 Jan 2012 11:07:40 -0500 Subject: [PATCH 15/18] segafilm: use the sample rate as the time base for audio streams --- libavformat/segafilm.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/libavformat/segafilm.c b/libavformat/segafilm.c index 83ba4f06ad..23cb3ed1ed 100644 --- a/libavformat/segafilm.c +++ b/libavformat/segafilm.c @@ -196,8 +196,13 @@ static int film_read_header(AVFormatContext *s) if (!film->sample_table) return AVERROR(ENOMEM); - for(i=0; inb_streams; i++) - avpriv_set_pts_info(s->streams[i], 33, 1, film->base_clock); + for (i = 0; i < s->nb_streams; i++) { + st = s->streams[i]; + if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) + avpriv_set_pts_info(st, 33, 1, film->base_clock); + else + avpriv_set_pts_info(st, 64, 1, film->audio_samplerate); + } audio_frame_counter = 0; for (i = 0; i < film->sample_count; i++) { @@ -212,8 +217,6 @@ static int film_read_header(AVFormatContext *s) if (AV_RB32(&scratch[8]) == 0xFFFFFFFF) { film->sample_table[i].stream = film->audio_stream_index; film->sample_table[i].pts = audio_frame_counter; - film->sample_table[i].pts *= film->base_clock; - film->sample_table[i].pts /= film->audio_samplerate; if (film->audio_type == CODEC_ID_ADPCM_ADX) audio_frame_counter += (film->sample_table[i].sample_size * 32 / From 0883109b27a9d2edf9528506e2605a5e0b8eef95 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Wed, 11 Jan 2012 21:10:35 -0500 Subject: [PATCH 16/18] voc/avs: Do not change the sample rate mid-stream. Also, set the time base based on the sample rate. lavf-voc seek test updated to reflect slightly different seek points. --- libavformat/vocdec.c | 16 ++++++++++++---- tests/ref/seek/lavf_voc | 24 ++++++++++++------------ 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/libavformat/vocdec.c b/libavformat/vocdec.c index e8c11afbe3..3c27062408 100644 --- a/libavformat/vocdec.c +++ b/libavformat/vocdec.c @@ -86,9 +86,13 @@ ff_voc_get_packet(AVFormatContext *s, AVPacket *pkt, AVStream *st, int max_size) switch (type) { case VOC_TYPE_VOICE_DATA: - dec->sample_rate = 1000000 / (256 - avio_r8(pb)); - if (sample_rate) - dec->sample_rate = sample_rate; + if (!dec->sample_rate) { + dec->sample_rate = 1000000 / (256 - avio_r8(pb)); + if (sample_rate) + dec->sample_rate = sample_rate; + avpriv_set_pts_info(st, 64, 1, dec->sample_rate); + } else + avio_skip(pb, 1); dec->channels = channels; tmp_codec = avio_r8(pb); dec->bits_per_coded_sample = av_get_bits_per_sample(dec->codec_id); @@ -110,7 +114,11 @@ ff_voc_get_packet(AVFormatContext *s, AVPacket *pkt, AVStream *st, int max_size) break; case VOC_TYPE_NEW_VOICE_DATA: - dec->sample_rate = avio_rl32(pb); + if (!dec->sample_rate) { + dec->sample_rate = avio_rl32(pb); + avpriv_set_pts_info(st, 64, 1, dec->sample_rate); + } else + avio_skip(pb, 4); dec->bits_per_coded_sample = avio_r8(pb); dec->channels = avio_r8(pb); tmp_codec = avio_rl16(pb); diff --git a/tests/ref/seek/lavf_voc b/tests/ref/seek/lavf_voc index 5670d1a992..387aef6cb8 100644 --- a/tests/ref/seek/lavf_voc +++ b/tests/ref/seek/lavf_voc @@ -1,27 +1,27 @@ ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 32 size: 1024 ret:-1 st:-1 flags:0 ts:-1.000000 ret:-1 st:-1 flags:1 ts: 1.894167 -ret:-1 st: 0 flags:0 ts: 0.788333 -ret:-1 st: 0 flags:1 ts:-0.317500 +ret:-1 st: 0 flags:0 ts: 0.788335 +ret:-1 st: 0 flags:1 ts:-0.317508 ret:-1 st:-1 flags:0 ts: 2.576668 ret:-1 st:-1 flags:1 ts: 1.470835 -ret:-1 st: 0 flags:0 ts: 0.365000 -ret:-1 st: 0 flags:1 ts:-0.740833 +ret:-1 st: 0 flags:0 ts: 0.365006 +ret:-1 st: 0 flags:1 ts:-0.740837 ret:-1 st:-1 flags:0 ts: 2.153336 ret:-1 st:-1 flags:1 ts: 1.047503 -ret:-1 st: 0 flags:0 ts:-0.058333 -ret:-1 st: 0 flags:1 ts: 2.835833 +ret:-1 st: 0 flags:0 ts:-0.058323 +ret:-1 st: 0 flags:1 ts: 2.835834 ret:-1 st:-1 flags:0 ts: 1.730004 ret:-1 st:-1 flags:1 ts: 0.624171 -ret:-1 st: 0 flags:0 ts:-0.481667 -ret:-1 st: 0 flags:1 ts: 2.412500 +ret:-1 st: 0 flags:0 ts:-0.481652 +ret:-1 st: 0 flags:1 ts: 2.412505 ret:-1 st:-1 flags:0 ts: 1.306672 ret:-1 st:-1 flags:1 ts: 0.200839 -ret:-1 st: 0 flags:0 ts:-0.904989 -ret:-1 st: 0 flags:1 ts: 1.989178 +ret:-1 st: 0 flags:0 ts:-0.905003 +ret:-1 st: 0 flags:1 ts: 1.989176 ret:-1 st:-1 flags:0 ts: 0.883340 ret:-1 st:-1 flags:1 ts:-0.222493 -ret:-1 st: 0 flags:0 ts: 2.671678 -ret:-1 st: 0 flags:1 ts: 1.565844 +ret:-1 st: 0 flags:0 ts: 2.671668 +ret:-1 st: 0 flags:1 ts: 1.565847 ret:-1 st:-1 flags:0 ts: 0.460008 ret:-1 st:-1 flags:1 ts:-0.645825 From f9cf91d8224eb9081e50b6cee55423ccb0bf9e90 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Thu, 19 Jan 2012 23:01:53 -0500 Subject: [PATCH 17/18] tiertexseq: set audio stream start time to 0 Update FATE test to reflect delayed video due to the file having audio-only frames prior to the first frame with video. --- libavformat/tiertexseq.c | 1 + tests/ref/fate/tiertex-seq | 42 +++++++++++++++++++------------------- 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/libavformat/tiertexseq.c b/libavformat/tiertexseq.c index 194c83abc1..16af084b39 100644 --- a/libavformat/tiertexseq.c +++ b/libavformat/tiertexseq.c @@ -224,6 +224,7 @@ static int seq_read_header(AVFormatContext *s) if (!st) return AVERROR(ENOMEM); + st->start_time = 0; avpriv_set_pts_info(st, 32, 1, SEQ_SAMPLE_RATE); seq->audio_stream_index = st->index; st->codec->codec_type = AVMEDIA_TYPE_AUDIO; diff --git a/tests/ref/fate/tiertex-seq b/tests/ref/fate/tiertex-seq index 595309342e..74407e7674 100644 --- a/tests/ref/fate/tiertex-seq +++ b/tests/ref/fate/tiertex-seq @@ -1,100 +1,100 @@ #tb 0: 1/25 #tb 1: 1/22050 -0, 0, 0, 1, 98304, 0x2e5db4a4 1, 0, 0, 882, 1764, 0x00000000 1, 882, 882, 882, 1764, 0x80a253d9 +0, 2, 2, 1, 98304, 0x2e5db4a4 1, 1764, 1764, 882, 1764, 0x95a16721 1, 2646, 2646, 882, 1764, 0x0f0d4cb6 -0, 4, 4, 1, 98304, 0xb20c19d0 1, 3528, 3528, 882, 1764, 0x75026779 1, 4410, 4410, 882, 1764, 0xb4356e37 +0, 6, 6, 1, 98304, 0xb20c19d0 1, 5292, 5292, 882, 1764, 0xfafa64cb -0, 7, 7, 1, 98304, 0x6b8538c0 1, 6174, 6174, 882, 1764, 0xe8fd7970 1, 7056, 7056, 882, 1764, 0x666879b7 +0, 9, 9, 1, 98304, 0x6b8538c0 1, 7938, 7938, 882, 1764, 0xf2cd7770 1, 8820, 8820, 882, 1764, 0x54317a1c -0, 11, 11, 1, 98304, 0x172207e3 1, 9702, 9702, 882, 1764, 0x9c396930 1, 10584, 10584, 882, 1764, 0x87115ec4 +0, 13, 13, 1, 98304, 0x172207e3 1, 11466, 11466, 882, 1764, 0x0c9b69b6 -0, 14, 14, 1, 98304, 0x63fb7dc1 1, 12348, 12348, 882, 1764, 0x8c3a758a 1, 13230, 13230, 882, 1764, 0x605d776a +0, 16, 16, 1, 98304, 0x63fb7dc1 1, 14112, 14112, 882, 1764, 0x0556852d 1, 14994, 14994, 882, 1764, 0x7d4363f8 -0, 18, 18, 1, 98304, 0x37cf1601 1, 15876, 15876, 882, 1764, 0xc5cd75d0 1, 16758, 16758, 882, 1764, 0x3ff3646d +0, 20, 20, 1, 98304, 0x37cf1601 1, 17640, 17640, 882, 1764, 0x10136d25 1, 18522, 18522, 882, 1764, 0xeb1a6cd0 -0, 22, 22, 1, 98304, 0x82941990 1, 19404, 19404, 882, 1764, 0xef937ed1 1, 20286, 20286, 882, 1764, 0x2d2b6f79 +0, 24, 24, 1, 98304, 0x82941990 1, 21168, 21168, 882, 1764, 0x6f457231 -0, 25, 25, 1, 98304, 0xe0a5309e 1, 22050, 22050, 882, 1764, 0x56267c9d 1, 22932, 22932, 882, 1764, 0xd49e79c8 +0, 27, 27, 1, 98304, 0xe0a5309e 1, 23814, 23814, 882, 1764, 0xc726703d 1, 24696, 24696, 882, 1764, 0x2abf8074 -0, 29, 29, 1, 98304, 0x164cb67d 1, 25578, 25578, 882, 1764, 0xb50c556d 1, 26460, 26460, 882, 1764, 0xc1f2523c +0, 31, 31, 1, 98304, 0x164cb67d 1, 27342, 27342, 882, 1764, 0x850a6f93 -0, 32, 32, 1, 98304, 0xed2189f8 1, 28224, 28224, 882, 1764, 0x8da76c31 1, 29106, 29106, 882, 1764, 0xfcccdf13 +0, 34, 34, 1, 98304, 0xed2189f8 1, 29988, 29988, 882, 1764, 0x00000000 1, 30870, 30870, 882, 1764, 0x00000000 -0, 36, 36, 1, 98304, 0x7215e529 1, 31752, 31752, 882, 1764, 0x00000000 1, 32634, 32634, 882, 1764, 0x00000000 +0, 38, 38, 1, 98304, 0x7215e529 1, 33516, 33516, 882, 1764, 0x00000000 -0, 39, 39, 1, 98304, 0x170c783b 1, 34398, 34398, 882, 1764, 0x00000000 1, 35280, 35280, 882, 1764, 0x00000000 +0, 41, 41, 1, 98304, 0x170c783b 1, 36162, 36162, 882, 1764, 0x00000000 1, 37044, 37044, 882, 1764, 0x00000000 -0, 43, 43, 1, 98304, 0xf6bd74c7 1, 37926, 37926, 882, 1764, 0x00000000 1, 38808, 38808, 882, 1764, 0x00000000 +0, 45, 45, 1, 98304, 0xf6bd74c7 1, 39690, 39690, 882, 1764, 0x00000000 1, 40572, 40572, 882, 1764, 0x00000000 -0, 47, 47, 1, 98304, 0x1efd38c4 1, 41454, 41454, 882, 1764, 0x00000000 1, 42336, 42336, 882, 1764, 0x00000000 +0, 49, 49, 1, 98304, 0x1efd38c4 1, 43218, 43218, 882, 1764, 0x00000000 -0, 50, 50, 1, 98304, 0x29c26bba 1, 44100, 44100, 882, 1764, 0x00000000 1, 44982, 44982, 882, 1764, 0x00000000 +0, 52, 52, 1, 98304, 0x29c26bba 1, 45864, 45864, 882, 1764, 0x00000000 1, 46746, 46746, 882, 1764, 0x00000000 -0, 54, 54, 1, 98304, 0x880a6313 1, 47628, 47628, 882, 1764, 0x00000000 1, 48510, 48510, 882, 1764, 0x00000000 +0, 56, 56, 1, 98304, 0x880a6313 1, 49392, 49392, 882, 1764, 0x00000000 -0, 57, 57, 1, 98304, 0x73f5bb00 1, 50274, 50274, 882, 1764, 0x00000000 1, 51156, 51156, 882, 1764, 0x00000000 +0, 59, 59, 1, 98304, 0x73f5bb00 1, 52038, 52038, 882, 1764, 0x00000000 1, 52920, 52920, 882, 1764, 0x00000000 -0, 61, 61, 1, 98304, 0xc85b19ec 1, 53802, 53802, 882, 1764, 0x00000000 1, 54684, 54684, 882, 1764, 0x00000000 +0, 63, 63, 1, 98304, 0xc85b19ec 1, 55566, 55566, 882, 1764, 0x00000000 -0, 64, 64, 1, 98304, 0x00000000 1, 56448, 56448, 882, 1764, 0x00000000 1, 57330, 57330, 882, 1764, 0x00000000 +0, 66, 66, 1, 98304, 0x00000000 1, 58212, 58212, 882, 1764, 0x00000000 1, 59094, 59094, 882, 1764, 0x00000000 -0, 68, 68, 1, 98304, 0x00000000 1, 59976, 59976, 882, 1764, 0x00000000 1, 60858, 60858, 882, 1764, 0x00000000 +0, 70, 70, 1, 98304, 0x00000000 1, 61740, 61740, 882, 1764, 0x00000000 1, 62622, 62622, 882, 1764, 0x00000000 -0, 72, 72, 1, 98304, 0x00000000 1, 63504, 63504, 882, 1764, 0x00000000 1, 64386, 64386, 882, 1764, 0x00000000 +0, 74, 74, 1, 98304, 0x00000000 1, 65268, 65268, 882, 1764, 0x00000000 1, 66150, 66150, 882, 1764, 0x00000000 1, 67032, 67032, 882, 1764, 0x00000000 From b7beabab4b78cc253d06c0a33f15b8ff79866e85 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Thu, 19 Jan 2012 23:03:08 -0500 Subject: [PATCH 18/18] tiertexseq: set correct block_align for audio --- libavformat/tiertexseq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/tiertexseq.c b/libavformat/tiertexseq.c index 16af084b39..df7c38d0d2 100644 --- a/libavformat/tiertexseq.c +++ b/libavformat/tiertexseq.c @@ -234,7 +234,7 @@ static int seq_read_header(AVFormatContext *s) st->codec->sample_rate = SEQ_SAMPLE_RATE; st->codec->bits_per_coded_sample = 16; st->codec->bit_rate = st->codec->sample_rate * st->codec->bits_per_coded_sample * st->codec->channels; - st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample; + st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample / 8; return 0; }