annotate ffmpeg/libavcodec/mlp_parser.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 6840f77b83aa
children
rev   line source
yading@10 1 /*
yading@10 2 * MLP parser
yading@10 3 * Copyright (c) 2007 Ian Caulfield
yading@10 4 *
yading@10 5 * This file is part of FFmpeg.
yading@10 6 *
yading@10 7 * FFmpeg is free software; you can redistribute it and/or
yading@10 8 * modify it under the terms of the GNU Lesser General Public
yading@10 9 * License as published by the Free Software Foundation; either
yading@10 10 * version 2.1 of the License, or (at your option) any later version.
yading@10 11 *
yading@10 12 * FFmpeg is distributed in the hope that it will be useful,
yading@10 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
yading@10 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
yading@10 15 * Lesser General Public License for more details.
yading@10 16 *
yading@10 17 * You should have received a copy of the GNU Lesser General Public
yading@10 18 * License along with FFmpeg; if not, write to the Free Software
yading@10 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
yading@10 20 */
yading@10 21
yading@10 22 /**
yading@10 23 * @file
yading@10 24 * MLP parser
yading@10 25 */
yading@10 26
yading@10 27 #include <stdint.h>
yading@10 28
yading@10 29 #include "libavutil/channel_layout.h"
yading@10 30 #include "libavutil/crc.h"
yading@10 31 #include "get_bits.h"
yading@10 32 #include "parser.h"
yading@10 33 #include "mlp_parser.h"
yading@10 34 #include "mlp.h"
yading@10 35
yading@10 36 static const uint8_t mlp_quants[16] = {
yading@10 37 16, 20, 24, 0, 0, 0, 0, 0,
yading@10 38 0, 0, 0, 0, 0, 0, 0, 0,
yading@10 39 };
yading@10 40
yading@10 41 static const uint8_t mlp_channels[32] = {
yading@10 42 1, 2, 3, 4, 3, 4, 5, 3, 4, 5, 4, 5, 6, 4, 5, 4,
yading@10 43 5, 6, 5, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
yading@10 44 };
yading@10 45
yading@10 46 const uint64_t ff_mlp_layout[32] = {
yading@10 47 AV_CH_LAYOUT_MONO,
yading@10 48 AV_CH_LAYOUT_STEREO,
yading@10 49 AV_CH_LAYOUT_2_1,
yading@10 50 AV_CH_LAYOUT_QUAD,
yading@10 51 AV_CH_LAYOUT_STEREO|AV_CH_LOW_FREQUENCY,
yading@10 52 AV_CH_LAYOUT_2_1|AV_CH_LOW_FREQUENCY,
yading@10 53 AV_CH_LAYOUT_QUAD|AV_CH_LOW_FREQUENCY,
yading@10 54 AV_CH_LAYOUT_SURROUND,
yading@10 55 AV_CH_LAYOUT_4POINT0,
yading@10 56 AV_CH_LAYOUT_5POINT0_BACK,
yading@10 57 AV_CH_LAYOUT_SURROUND|AV_CH_LOW_FREQUENCY,
yading@10 58 AV_CH_LAYOUT_4POINT0|AV_CH_LOW_FREQUENCY,
yading@10 59 AV_CH_LAYOUT_5POINT1_BACK,
yading@10 60 AV_CH_LAYOUT_4POINT0,
yading@10 61 AV_CH_LAYOUT_5POINT0_BACK,
yading@10 62 AV_CH_LAYOUT_SURROUND|AV_CH_LOW_FREQUENCY,
yading@10 63 AV_CH_LAYOUT_4POINT0|AV_CH_LOW_FREQUENCY,
yading@10 64 AV_CH_LAYOUT_5POINT1_BACK,
yading@10 65 AV_CH_LAYOUT_QUAD|AV_CH_LOW_FREQUENCY,
yading@10 66 AV_CH_LAYOUT_5POINT0_BACK,
yading@10 67 AV_CH_LAYOUT_5POINT1_BACK,
yading@10 68 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
yading@10 69 };
yading@10 70
yading@10 71 static const uint8_t thd_chancount[13] = {
yading@10 72 // LR C LFE LRs LRvh LRc LRrs Cs Ts LRsd LRw Cvh LFE2
yading@10 73 2, 1, 1, 2, 2, 2, 2, 1, 1, 2, 2, 1, 1
yading@10 74 };
yading@10 75
yading@10 76 static const uint64_t thd_layout[13] = {
yading@10 77 AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT, // LR
yading@10 78 AV_CH_FRONT_CENTER, // C
yading@10 79 AV_CH_LOW_FREQUENCY, // LFE
yading@10 80 AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT, // LRs
yading@10 81 AV_CH_TOP_FRONT_LEFT|AV_CH_TOP_FRONT_RIGHT, // LRvh
yading@10 82 AV_CH_FRONT_LEFT_OF_CENTER|AV_CH_FRONT_RIGHT_OF_CENTER, // LRc
yading@10 83 AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT, // LRrs
yading@10 84 AV_CH_BACK_CENTER, // Cs
yading@10 85 AV_CH_TOP_CENTER, // Ts
yading@10 86 AV_CH_SURROUND_DIRECT_LEFT|AV_CH_SURROUND_DIRECT_RIGHT, // LRsd
yading@10 87 AV_CH_WIDE_LEFT|AV_CH_WIDE_RIGHT, // LRw
yading@10 88 AV_CH_TOP_FRONT_CENTER, // Cvh
yading@10 89 AV_CH_LOW_FREQUENCY_2, // LFE2
yading@10 90 };
yading@10 91
yading@10 92 static int mlp_samplerate(int in)
yading@10 93 {
yading@10 94 if (in == 0xF)
yading@10 95 return 0;
yading@10 96
yading@10 97 return (in & 8 ? 44100 : 48000) << (in & 7) ;
yading@10 98 }
yading@10 99
yading@10 100 static int truehd_channels(int chanmap)
yading@10 101 {
yading@10 102 int channels = 0, i;
yading@10 103
yading@10 104 for (i = 0; i < 13; i++)
yading@10 105 channels += thd_chancount[i] * ((chanmap >> i) & 1);
yading@10 106
yading@10 107 return channels;
yading@10 108 }
yading@10 109
yading@10 110 uint64_t ff_truehd_layout(int chanmap)
yading@10 111 {
yading@10 112 int i;
yading@10 113 uint64_t layout = 0;
yading@10 114
yading@10 115 for (i = 0; i < 13; i++)
yading@10 116 layout |= thd_layout[i] * ((chanmap >> i) & 1);
yading@10 117
yading@10 118 return layout;
yading@10 119 }
yading@10 120
yading@10 121 /** Read a major sync info header - contains high level information about
yading@10 122 * the stream - sample rate, channel arrangement etc. Most of this
yading@10 123 * information is not actually necessary for decoding, only for playback.
yading@10 124 * gb must be a freshly initialized GetBitContext with no bits read.
yading@10 125 */
yading@10 126
yading@10 127 int ff_mlp_read_major_sync(void *log, MLPHeaderInfo *mh, GetBitContext *gb)
yading@10 128 {
yading@10 129 int ratebits, channel_arrangement;
yading@10 130 uint16_t checksum;
yading@10 131
yading@10 132 av_assert1(get_bits_count(gb) == 0);
yading@10 133
yading@10 134 if (gb->size_in_bits < 28 << 3) {
yading@10 135 av_log(log, AV_LOG_ERROR, "packet too short, unable to read major sync\n");
yading@10 136 return -1;
yading@10 137 }
yading@10 138
yading@10 139 checksum = ff_mlp_checksum16(gb->buffer, 26);
yading@10 140 if (checksum != AV_RL16(gb->buffer+26)) {
yading@10 141 av_log(log, AV_LOG_ERROR, "major sync info header checksum error\n");
yading@10 142 return AVERROR_INVALIDDATA;
yading@10 143 }
yading@10 144
yading@10 145 if (get_bits_long(gb, 24) != 0xf8726f) /* Sync words */
yading@10 146 return AVERROR_INVALIDDATA;
yading@10 147
yading@10 148 mh->stream_type = get_bits(gb, 8);
yading@10 149
yading@10 150 if (mh->stream_type == 0xbb) {
yading@10 151 mh->group1_bits = mlp_quants[get_bits(gb, 4)];
yading@10 152 mh->group2_bits = mlp_quants[get_bits(gb, 4)];
yading@10 153
yading@10 154 ratebits = get_bits(gb, 4);
yading@10 155 mh->group1_samplerate = mlp_samplerate(ratebits);
yading@10 156 mh->group2_samplerate = mlp_samplerate(get_bits(gb, 4));
yading@10 157
yading@10 158 skip_bits(gb, 11);
yading@10 159
yading@10 160 mh->channel_arrangement=
yading@10 161 channel_arrangement = get_bits(gb, 5);
yading@10 162 mh->channels_mlp = mlp_channels[channel_arrangement];
yading@10 163 mh->channel_layout_mlp = ff_mlp_layout[channel_arrangement];
yading@10 164 } else if (mh->stream_type == 0xba) {
yading@10 165 mh->group1_bits = 24; // TODO: Is this information actually conveyed anywhere?
yading@10 166 mh->group2_bits = 0;
yading@10 167
yading@10 168 ratebits = get_bits(gb, 4);
yading@10 169 mh->group1_samplerate = mlp_samplerate(ratebits);
yading@10 170 mh->group2_samplerate = 0;
yading@10 171
yading@10 172 skip_bits(gb, 8);
yading@10 173
yading@10 174 mh->channel_arrangement=
yading@10 175 channel_arrangement = get_bits(gb, 5);
yading@10 176 mh->channels_thd_stream1 = truehd_channels(channel_arrangement);
yading@10 177 mh->channel_layout_thd_stream1 = ff_truehd_layout(channel_arrangement);
yading@10 178
yading@10 179 skip_bits(gb, 2);
yading@10 180
yading@10 181 channel_arrangement = get_bits(gb, 13);
yading@10 182 mh->channels_thd_stream2 = truehd_channels(channel_arrangement);
yading@10 183 mh->channel_layout_thd_stream2 = ff_truehd_layout(channel_arrangement);
yading@10 184 } else
yading@10 185 return AVERROR_INVALIDDATA;
yading@10 186
yading@10 187 mh->access_unit_size = 40 << (ratebits & 7);
yading@10 188 mh->access_unit_size_pow2 = 64 << (ratebits & 7);
yading@10 189
yading@10 190 skip_bits_long(gb, 48);
yading@10 191
yading@10 192 mh->is_vbr = get_bits1(gb);
yading@10 193
yading@10 194 mh->peak_bitrate = (get_bits(gb, 15) * mh->group1_samplerate + 8) >> 4;
yading@10 195
yading@10 196 mh->num_substreams = get_bits(gb, 4);
yading@10 197
yading@10 198 skip_bits_long(gb, 4 + 11 * 8);
yading@10 199
yading@10 200 return 0;
yading@10 201 }
yading@10 202
yading@10 203 typedef struct MLPParseContext
yading@10 204 {
yading@10 205 ParseContext pc;
yading@10 206
yading@10 207 int bytes_left;
yading@10 208
yading@10 209 int in_sync;
yading@10 210
yading@10 211 int num_substreams;
yading@10 212 } MLPParseContext;
yading@10 213
yading@10 214 static av_cold int mlp_init(AVCodecParserContext *s)
yading@10 215 {
yading@10 216 ff_mlp_init_crc();
yading@10 217 return 0;
yading@10 218 }
yading@10 219
yading@10 220 static int mlp_parse(AVCodecParserContext *s,
yading@10 221 AVCodecContext *avctx,
yading@10 222 const uint8_t **poutbuf, int *poutbuf_size,
yading@10 223 const uint8_t *buf, int buf_size)
yading@10 224 {
yading@10 225 MLPParseContext *mp = s->priv_data;
yading@10 226 int sync_present;
yading@10 227 uint8_t parity_bits;
yading@10 228 int next;
yading@10 229 int i, p = 0;
yading@10 230
yading@10 231 *poutbuf_size = 0;
yading@10 232 if (buf_size == 0)
yading@10 233 return 0;
yading@10 234
yading@10 235 if (!mp->in_sync) {
yading@10 236 // Not in sync - find a major sync header
yading@10 237
yading@10 238 for (i = 0; i < buf_size; i++) {
yading@10 239 mp->pc.state = (mp->pc.state << 8) | buf[i];
yading@10 240 if ((mp->pc.state & 0xfffffffe) == 0xf8726fba &&
yading@10 241 // ignore if we do not have the data for the start of header
yading@10 242 mp->pc.index + i >= 7) {
yading@10 243 mp->in_sync = 1;
yading@10 244 mp->bytes_left = 0;
yading@10 245 break;
yading@10 246 }
yading@10 247 }
yading@10 248
yading@10 249 if (!mp->in_sync) {
yading@10 250 if (ff_combine_frame(&mp->pc, END_NOT_FOUND, &buf, &buf_size) != -1)
yading@10 251 av_log(avctx, AV_LOG_WARNING, "ff_combine_frame failed\n");
yading@10 252 return buf_size;
yading@10 253 }
yading@10 254
yading@10 255 ff_combine_frame(&mp->pc, i - 7, &buf, &buf_size);
yading@10 256
yading@10 257 return i - 7;
yading@10 258 }
yading@10 259
yading@10 260 if (mp->bytes_left == 0) {
yading@10 261 // Find length of this packet
yading@10 262
yading@10 263 /* Copy overread bytes from last frame into buffer. */
yading@10 264 for(; mp->pc.overread>0; mp->pc.overread--) {
yading@10 265 mp->pc.buffer[mp->pc.index++]= mp->pc.buffer[mp->pc.overread_index++];
yading@10 266 }
yading@10 267
yading@10 268 if (mp->pc.index + buf_size < 2) {
yading@10 269 if (ff_combine_frame(&mp->pc, END_NOT_FOUND, &buf, &buf_size) != -1)
yading@10 270 av_log(avctx, AV_LOG_WARNING, "ff_combine_frame failed\n");
yading@10 271 return buf_size;
yading@10 272 }
yading@10 273
yading@10 274 mp->bytes_left = ((mp->pc.index > 0 ? mp->pc.buffer[0] : buf[0]) << 8)
yading@10 275 | (mp->pc.index > 1 ? mp->pc.buffer[1] : buf[1-mp->pc.index]);
yading@10 276 mp->bytes_left = (mp->bytes_left & 0xfff) * 2;
yading@10 277 if (mp->bytes_left <= 0) { // prevent infinite loop
yading@10 278 goto lost_sync;
yading@10 279 }
yading@10 280 mp->bytes_left -= mp->pc.index;
yading@10 281 }
yading@10 282
yading@10 283 next = (mp->bytes_left > buf_size) ? END_NOT_FOUND : mp->bytes_left;
yading@10 284
yading@10 285 if (ff_combine_frame(&mp->pc, next, &buf, &buf_size) < 0) {
yading@10 286 mp->bytes_left -= buf_size;
yading@10 287 return buf_size;
yading@10 288 }
yading@10 289
yading@10 290 mp->bytes_left = 0;
yading@10 291
yading@10 292 sync_present = (AV_RB32(buf + 4) & 0xfffffffe) == 0xf8726fba;
yading@10 293
yading@10 294 if (!sync_present) {
yading@10 295 /* The first nibble of a frame is a parity check of the 4-byte
yading@10 296 * access unit header and all the 2- or 4-byte substream headers. */
yading@10 297 // Only check when this isn't a sync frame - syncs have a checksum.
yading@10 298
yading@10 299 parity_bits = 0;
yading@10 300 for (i = -1; i < mp->num_substreams; i++) {
yading@10 301 parity_bits ^= buf[p++];
yading@10 302 parity_bits ^= buf[p++];
yading@10 303
yading@10 304 if (i < 0 || buf[p-2] & 0x80) {
yading@10 305 parity_bits ^= buf[p++];
yading@10 306 parity_bits ^= buf[p++];
yading@10 307 }
yading@10 308 }
yading@10 309
yading@10 310 if ((((parity_bits >> 4) ^ parity_bits) & 0xF) != 0xF) {
yading@10 311 av_log(avctx, AV_LOG_INFO, "mlpparse: Parity check failed.\n");
yading@10 312 goto lost_sync;
yading@10 313 }
yading@10 314 } else {
yading@10 315 GetBitContext gb;
yading@10 316 MLPHeaderInfo mh;
yading@10 317
yading@10 318 init_get_bits(&gb, buf + 4, (buf_size - 4) << 3);
yading@10 319 if (ff_mlp_read_major_sync(avctx, &mh, &gb) < 0)
yading@10 320 goto lost_sync;
yading@10 321
yading@10 322 avctx->bits_per_raw_sample = mh.group1_bits;
yading@10 323 if (avctx->bits_per_raw_sample > 16)
yading@10 324 avctx->sample_fmt = AV_SAMPLE_FMT_S32;
yading@10 325 else
yading@10 326 avctx->sample_fmt = AV_SAMPLE_FMT_S16;
yading@10 327 avctx->sample_rate = mh.group1_samplerate;
yading@10 328 s->duration = mh.access_unit_size;
yading@10 329
yading@10 330 if(!avctx->channels || !avctx->channel_layout) {
yading@10 331 if (mh.stream_type == 0xbb) {
yading@10 332 /* MLP stream */
yading@10 333 #if FF_API_REQUEST_CHANNELS
yading@10 334 if (avctx->request_channels > 0 && avctx->request_channels <= 2 &&
yading@10 335 mh.num_substreams > 1) {
yading@10 336 avctx->channels = 2;
yading@10 337 avctx->channel_layout = AV_CH_LAYOUT_STEREO;
yading@10 338 } else
yading@10 339 #endif
yading@10 340 if (avctx->request_channel_layout == AV_CH_LAYOUT_STEREO &&
yading@10 341 mh.num_substreams > 1) {
yading@10 342 avctx->channels = 2;
yading@10 343 avctx->channel_layout = AV_CH_LAYOUT_STEREO;
yading@10 344 } else {
yading@10 345 avctx->channels = mh.channels_mlp;
yading@10 346 avctx->channel_layout = mh.channel_layout_mlp;
yading@10 347 }
yading@10 348 } else { /* mh.stream_type == 0xba */
yading@10 349 /* TrueHD stream */
yading@10 350 #if FF_API_REQUEST_CHANNELS
yading@10 351 if (avctx->request_channels > 0 && avctx->request_channels <= 2 &&
yading@10 352 mh.num_substreams > 1) {
yading@10 353 avctx->channels = 2;
yading@10 354 avctx->channel_layout = AV_CH_LAYOUT_STEREO;
yading@10 355 } else if (avctx->request_channels > 0 &&
yading@10 356 avctx->request_channels <= mh.channels_thd_stream1) {
yading@10 357 avctx->channels = mh.channels_thd_stream1;
yading@10 358 avctx->channel_layout = mh.channel_layout_thd_stream1;
yading@10 359 } else
yading@10 360 #endif
yading@10 361 if (avctx->request_channel_layout == AV_CH_LAYOUT_STEREO &&
yading@10 362 mh.num_substreams > 1) {
yading@10 363 avctx->channels = 2;
yading@10 364 avctx->channel_layout = AV_CH_LAYOUT_STEREO;
yading@10 365 } else if (avctx->request_channel_layout == mh.channel_layout_thd_stream1 ||
yading@10 366 !mh.channels_thd_stream2) {
yading@10 367 avctx->channels = mh.channels_thd_stream1;
yading@10 368 avctx->channel_layout = mh.channel_layout_thd_stream1;
yading@10 369 } else {
yading@10 370 avctx->channels = mh.channels_thd_stream2;
yading@10 371 avctx->channel_layout = mh.channel_layout_thd_stream2;
yading@10 372 }
yading@10 373 }
yading@10 374 }
yading@10 375
yading@10 376 if (!mh.is_vbr) /* Stream is CBR */
yading@10 377 avctx->bit_rate = mh.peak_bitrate;
yading@10 378
yading@10 379 mp->num_substreams = mh.num_substreams;
yading@10 380 }
yading@10 381
yading@10 382 *poutbuf = buf;
yading@10 383 *poutbuf_size = buf_size;
yading@10 384
yading@10 385 return next;
yading@10 386
yading@10 387 lost_sync:
yading@10 388 mp->in_sync = 0;
yading@10 389 return 1;
yading@10 390 }
yading@10 391
yading@10 392 AVCodecParser ff_mlp_parser = {
yading@10 393 .codec_ids = { AV_CODEC_ID_MLP, AV_CODEC_ID_TRUEHD },
yading@10 394 .priv_data_size = sizeof(MLPParseContext),
yading@10 395 .parser_init = mlp_init,
yading@10 396 .parser_parse = mlp_parse,
yading@10 397 .parser_close = ff_parse_close,
yading@10 398 };