Mercurial > libavformat.hg
view adtsenc.c @ 1206:e60bf67d9bf8 libavformat
The reader ignores the size of the ASF data object and keeps on
reading even beyond it.
Therefore if the ASF file includes an index object at its end, the
reader will treat the index like data, but of course will fail since
it thinks that the data is corrupted.
When reading an asf file with an index object, ffmpeg will
complain at the end of the file that it read an invalid header.
Patch by Kohn Emil Dan, < emild A cs P technion P ac P il >
Original thead:
Date: Apr 18, 2006 4:11 PM
Subject: [Ffmpeg-devel] Two ASF related bugs and fixes
author | gpoirier |
---|---|
date | Sat, 29 Jul 2006 16:07:19 +0000 |
parents | d18cc9a1fd02 |
children | 0899bfe4105c |
line wrap: on
line source
/* * ADTS muxer. * Copyright (c) 2006 Baptiste Coudurier <baptiste.coudurier@smartjog.com> * Mans Rullgard <mru@inprovide.com> * * This library 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 of the License, or (at your option) any later version. * * This library 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 this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "avformat.h" #include "bitstream.h" #define ADTS_HEADER_SIZE 7 typedef struct { int write_adts; int objecttype; int sample_rate_index; int channel_conf; } ADTSContext; static int decode_extradata(ADTSContext *adts, uint8_t *buf, int size) { GetBitContext gb; init_get_bits(&gb, buf, size * 8); adts->objecttype = get_bits(&gb, 5) - 1; adts->sample_rate_index = get_bits(&gb, 4); adts->channel_conf = get_bits(&gb, 4); adts->write_adts = 1; return 0; } static int adts_write_header(AVFormatContext *s) { ADTSContext *adts = s->priv_data; AVCodecContext *avc = s->streams[0]->codec; if(avc->extradata_size > 0) decode_extradata(adts, avc->extradata, avc->extradata_size); return 0; } static int adts_write_frame_header(AVFormatContext *s, int size) { ADTSContext *ctx = s->priv_data; PutBitContext pb; uint8_t buf[ADTS_HEADER_SIZE]; init_put_bits(&pb, buf, ADTS_HEADER_SIZE); /* adts_fixed_header */ put_bits(&pb, 12, 0xfff); /* syncword */ put_bits(&pb, 1, 0); /* ID */ put_bits(&pb, 2, 0); /* layer */ put_bits(&pb, 1, 1); /* protection_absent */ put_bits(&pb, 2, ctx->objecttype); /* profile_objecttype */ put_bits(&pb, 4, ctx->sample_rate_index); put_bits(&pb, 1, 0); /* private_bit */ put_bits(&pb, 3, ctx->channel_conf); /* channel_configuration */ put_bits(&pb, 1, 0); /* original_copy */ put_bits(&pb, 1, 0); /* home */ /* adts_variable_header */ put_bits(&pb, 1, 0); /* copyright_identification_bit */ put_bits(&pb, 1, 0); /* copyright_identification_start */ put_bits(&pb, 13, ADTS_HEADER_SIZE + size); /* aac_frame_length */ put_bits(&pb, 11, 0x7ff); /* adts_buffer_fullness */ put_bits(&pb, 2, 0); /* number_of_raw_data_blocks_in_frame */ flush_put_bits(&pb); put_buffer(&s->pb, buf, ADTS_HEADER_SIZE); return 0; } static int adts_write_trailer(AVFormatContext *s) { return 0; } static int adts_write_packet(AVFormatContext *s, AVPacket *pkt) { ADTSContext *adts = s->priv_data; ByteIOContext *pb = &s->pb; if (!pkt->size) return 0; if(adts->write_adts) adts_write_frame_header(s, pkt->size); put_buffer(pb, pkt->data, pkt->size); put_flush_packet(pb); return 0; } AVOutputFormat adts_muxer = { "adts", "ADTS AAC", "audio/aac", "aac", sizeof(ADTSContext), CODEC_ID_AAC, CODEC_ID_NONE, adts_write_header, adts_write_packet, adts_write_trailer, };