annotate ffmpeg/libavformat/oggparseogm.c @ 13:844d341cf643 tip

Back up before ISMIR
author Yading Song <yading.song@eecs.qmul.ac.uk>
date Thu, 31 Oct 2013 13:17:06 +0000
parents f445c3017523
children
rev   line source
yading@11 1 /**
yading@11 2 Copyright (C) 2005 Michael Ahlberg, Måns Rullgård
yading@11 3
yading@11 4 Permission is hereby granted, free of charge, to any person
yading@11 5 obtaining a copy of this software and associated documentation
yading@11 6 files (the "Software"), to deal in the Software without
yading@11 7 restriction, including without limitation the rights to use, copy,
yading@11 8 modify, merge, publish, distribute, sublicense, and/or sell copies
yading@11 9 of the Software, and to permit persons to whom the Software is
yading@11 10 furnished to do so, subject to the following conditions:
yading@11 11
yading@11 12 The above copyright notice and this permission notice shall be
yading@11 13 included in all copies or substantial portions of the Software.
yading@11 14
yading@11 15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
yading@11 16 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
yading@11 17 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
yading@11 18 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
yading@11 19 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
yading@11 20 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
yading@11 21 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
yading@11 22 DEALINGS IN THE SOFTWARE.
yading@11 23 **/
yading@11 24
yading@11 25 #include <stdlib.h>
yading@11 26 #include "libavutil/avassert.h"
yading@11 27 #include "libavutil/intreadwrite.h"
yading@11 28 #include "libavcodec/get_bits.h"
yading@11 29 #include "libavcodec/bytestream.h"
yading@11 30 #include "avformat.h"
yading@11 31 #include "internal.h"
yading@11 32 #include "oggdec.h"
yading@11 33 #include "riff.h"
yading@11 34
yading@11 35 static int
yading@11 36 ogm_header(AVFormatContext *s, int idx)
yading@11 37 {
yading@11 38 struct ogg *ogg = s->priv_data;
yading@11 39 struct ogg_stream *os = ogg->streams + idx;
yading@11 40 AVStream *st = s->streams[idx];
yading@11 41 const uint8_t *p = os->buf + os->pstart;
yading@11 42 uint64_t time_unit;
yading@11 43 uint64_t spu;
yading@11 44 uint32_t size;
yading@11 45
yading@11 46 if(!(*p & 1))
yading@11 47 return 0;
yading@11 48
yading@11 49 if(*p == 1) {
yading@11 50 p++;
yading@11 51
yading@11 52 if(*p == 'v'){
yading@11 53 int tag;
yading@11 54 st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
yading@11 55 p += 8;
yading@11 56 tag = bytestream_get_le32(&p);
yading@11 57 st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, tag);
yading@11 58 st->codec->codec_tag = tag;
yading@11 59 } else if (*p == 't') {
yading@11 60 st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
yading@11 61 st->codec->codec_id = AV_CODEC_ID_TEXT;
yading@11 62 p += 12;
yading@11 63 } else {
yading@11 64 uint8_t acid[5];
yading@11 65 int cid;
yading@11 66 st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
yading@11 67 p += 8;
yading@11 68 bytestream_get_buffer(&p, acid, 4);
yading@11 69 acid[4] = 0;
yading@11 70 cid = strtol(acid, NULL, 16);
yading@11 71 st->codec->codec_id = ff_codec_get_id(ff_codec_wav_tags, cid);
yading@11 72 // our parser completely breaks AAC in Ogg
yading@11 73 if (st->codec->codec_id != AV_CODEC_ID_AAC)
yading@11 74 st->need_parsing = AVSTREAM_PARSE_FULL;
yading@11 75 }
yading@11 76
yading@11 77 size = bytestream_get_le32(&p);
yading@11 78 size = FFMIN(size, os->psize);
yading@11 79 time_unit = bytestream_get_le64(&p);
yading@11 80 spu = bytestream_get_le64(&p);
yading@11 81 p += 4; /* default_len */
yading@11 82 p += 8; /* buffersize + bits_per_sample */
yading@11 83
yading@11 84 if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO){
yading@11 85 st->codec->width = bytestream_get_le32(&p);
yading@11 86 st->codec->height = bytestream_get_le32(&p);
yading@11 87 avpriv_set_pts_info(st, 64, time_unit, spu * 10000000);
yading@11 88 } else {
yading@11 89 st->codec->channels = bytestream_get_le16(&p);
yading@11 90 p += 2; /* block_align */
yading@11 91 st->codec->bit_rate = bytestream_get_le32(&p) * 8;
yading@11 92 st->codec->sample_rate = time_unit ? spu * 10000000 / time_unit : 0;
yading@11 93 avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
yading@11 94 if (size >= 56 && st->codec->codec_id == AV_CODEC_ID_AAC) {
yading@11 95 p += 4;
yading@11 96 size -= 4;
yading@11 97 }
yading@11 98 if (size > 52) {
yading@11 99 av_assert0(FF_INPUT_BUFFER_PADDING_SIZE <= 52);
yading@11 100 size -= 52;
yading@11 101 st->codec->extradata_size = size;
yading@11 102 st->codec->extradata = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE);
yading@11 103 bytestream_get_buffer(&p, st->codec->extradata, size);
yading@11 104 }
yading@11 105 }
yading@11 106 } else if (*p == 3) {
yading@11 107 if (os->psize > 8)
yading@11 108 ff_vorbis_comment(s, &st->metadata, p+7, os->psize-8);
yading@11 109 }
yading@11 110
yading@11 111 return 1;
yading@11 112 }
yading@11 113
yading@11 114 static int
yading@11 115 ogm_dshow_header(AVFormatContext *s, int idx)
yading@11 116 {
yading@11 117 struct ogg *ogg = s->priv_data;
yading@11 118 struct ogg_stream *os = ogg->streams + idx;
yading@11 119 AVStream *st = s->streams[idx];
yading@11 120 uint8_t *p = os->buf + os->pstart;
yading@11 121 uint32_t t;
yading@11 122
yading@11 123 if(!(*p & 1))
yading@11 124 return 0;
yading@11 125 if(*p != 1)
yading@11 126 return 1;
yading@11 127
yading@11 128 t = AV_RL32(p + 96);
yading@11 129
yading@11 130 if(t == 0x05589f80){
yading@11 131 st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
yading@11 132 st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, AV_RL32(p + 68));
yading@11 133 avpriv_set_pts_info(st, 64, AV_RL64(p + 164), 10000000);
yading@11 134 st->codec->width = AV_RL32(p + 176);
yading@11 135 st->codec->height = AV_RL32(p + 180);
yading@11 136 } else if(t == 0x05589f81){
yading@11 137 st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
yading@11 138 st->codec->codec_id = ff_codec_get_id(ff_codec_wav_tags, AV_RL16(p + 124));
yading@11 139 st->codec->channels = AV_RL16(p + 126);
yading@11 140 st->codec->sample_rate = AV_RL32(p + 128);
yading@11 141 st->codec->bit_rate = AV_RL32(p + 132) * 8;
yading@11 142 }
yading@11 143
yading@11 144 return 1;
yading@11 145 }
yading@11 146
yading@11 147 static int
yading@11 148 ogm_packet(AVFormatContext *s, int idx)
yading@11 149 {
yading@11 150 struct ogg *ogg = s->priv_data;
yading@11 151 struct ogg_stream *os = ogg->streams + idx;
yading@11 152 uint8_t *p = os->buf + os->pstart;
yading@11 153 int lb;
yading@11 154
yading@11 155 if(*p & 8)
yading@11 156 os->pflags |= AV_PKT_FLAG_KEY;
yading@11 157
yading@11 158 lb = ((*p & 2) << 1) | ((*p >> 6) & 3);
yading@11 159 os->pstart += lb + 1;
yading@11 160 os->psize -= lb + 1;
yading@11 161
yading@11 162 while (lb--)
yading@11 163 os->pduration += p[lb+1] << (lb*8);
yading@11 164
yading@11 165 return 0;
yading@11 166 }
yading@11 167
yading@11 168 const struct ogg_codec ff_ogm_video_codec = {
yading@11 169 .magic = "\001video",
yading@11 170 .magicsize = 6,
yading@11 171 .header = ogm_header,
yading@11 172 .packet = ogm_packet,
yading@11 173 .granule_is_start = 1,
yading@11 174 .nb_header = 2,
yading@11 175 };
yading@11 176
yading@11 177 const struct ogg_codec ff_ogm_audio_codec = {
yading@11 178 .magic = "\001audio",
yading@11 179 .magicsize = 6,
yading@11 180 .header = ogm_header,
yading@11 181 .packet = ogm_packet,
yading@11 182 .granule_is_start = 1,
yading@11 183 .nb_header = 2,
yading@11 184 };
yading@11 185
yading@11 186 const struct ogg_codec ff_ogm_text_codec = {
yading@11 187 .magic = "\001text",
yading@11 188 .magicsize = 5,
yading@11 189 .header = ogm_header,
yading@11 190 .packet = ogm_packet,
yading@11 191 .granule_is_start = 1,
yading@11 192 .nb_header = 2,
yading@11 193 };
yading@11 194
yading@11 195 const struct ogg_codec ff_ogm_old_codec = {
yading@11 196 .magic = "\001Direct Show Samples embedded in Ogg",
yading@11 197 .magicsize = 35,
yading@11 198 .header = ogm_dshow_header,
yading@11 199 .packet = ogm_packet,
yading@11 200 .granule_is_start = 1,
yading@11 201 .nb_header = 1,
yading@11 202 };