Libav
|
00001 /* 00002 * MLP parser 00003 * Copyright (c) 2007 Ian Caulfield 00004 * 00005 * This file is part of FFmpeg. 00006 * 00007 * FFmpeg is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * FFmpeg is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with FFmpeg; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00020 */ 00021 00027 #include <stdint.h> 00028 00029 #include "libavutil/crc.h" 00030 #include "get_bits.h" 00031 #include "parser.h" 00032 #include "mlp_parser.h" 00033 #include "mlp.h" 00034 00035 static const uint8_t mlp_quants[16] = { 00036 16, 20, 24, 0, 0, 0, 0, 0, 00037 0, 0, 0, 0, 0, 0, 0, 0, 00038 }; 00039 00040 static const uint8_t mlp_channels[32] = { 00041 1, 2, 3, 4, 3, 4, 5, 3, 4, 5, 4, 5, 6, 4, 5, 4, 00042 5, 6, 5, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 00043 }; 00044 00045 static const uint8_t thd_chancount[13] = { 00046 // LR C LFE LRs LRvh LRc LRrs Cs Ts LRsd LRw Cvh LFE2 00047 2, 1, 1, 2, 2, 2, 2, 1, 1, 2, 2, 1, 1 00048 }; 00049 00050 static int mlp_samplerate(int in) 00051 { 00052 if (in == 0xF) 00053 return 0; 00054 00055 return (in & 8 ? 44100 : 48000) << (in & 7) ; 00056 } 00057 00058 static int truehd_channels(int chanmap) 00059 { 00060 int channels = 0, i; 00061 00062 for (i = 0; i < 13; i++) 00063 channels += thd_chancount[i] * ((chanmap >> i) & 1); 00064 00065 return channels; 00066 } 00067 00074 int ff_mlp_read_major_sync(void *log, MLPHeaderInfo *mh, GetBitContext *gb) 00075 { 00076 int ratebits; 00077 uint16_t checksum; 00078 00079 assert(get_bits_count(gb) == 0); 00080 00081 if (gb->size_in_bits < 28 << 3) { 00082 av_log(log, AV_LOG_ERROR, "packet too short, unable to read major sync\n"); 00083 return -1; 00084 } 00085 00086 checksum = ff_mlp_checksum16(gb->buffer, 26); 00087 if (checksum != AV_RL16(gb->buffer+26)) { 00088 av_log(log, AV_LOG_ERROR, "major sync info header checksum error\n"); 00089 return -1; 00090 } 00091 00092 if (get_bits_long(gb, 24) != 0xf8726f) /* Sync words */ 00093 return -1; 00094 00095 mh->stream_type = get_bits(gb, 8); 00096 00097 if (mh->stream_type == 0xbb) { 00098 mh->group1_bits = mlp_quants[get_bits(gb, 4)]; 00099 mh->group2_bits = mlp_quants[get_bits(gb, 4)]; 00100 00101 ratebits = get_bits(gb, 4); 00102 mh->group1_samplerate = mlp_samplerate(ratebits); 00103 mh->group2_samplerate = mlp_samplerate(get_bits(gb, 4)); 00104 00105 skip_bits(gb, 11); 00106 00107 mh->channels_mlp = get_bits(gb, 5); 00108 } else if (mh->stream_type == 0xba) { 00109 mh->group1_bits = 24; // TODO: Is this information actually conveyed anywhere? 00110 mh->group2_bits = 0; 00111 00112 ratebits = get_bits(gb, 4); 00113 mh->group1_samplerate = mlp_samplerate(ratebits); 00114 mh->group2_samplerate = 0; 00115 00116 skip_bits(gb, 8); 00117 00118 mh->channels_thd_stream1 = get_bits(gb, 5); 00119 00120 skip_bits(gb, 2); 00121 00122 mh->channels_thd_stream2 = get_bits(gb, 13); 00123 } else 00124 return -1; 00125 00126 mh->access_unit_size = 40 << (ratebits & 7); 00127 mh->access_unit_size_pow2 = 64 << (ratebits & 7); 00128 00129 skip_bits_long(gb, 48); 00130 00131 mh->is_vbr = get_bits1(gb); 00132 00133 mh->peak_bitrate = (get_bits(gb, 15) * mh->group1_samplerate + 8) >> 4; 00134 00135 mh->num_substreams = get_bits(gb, 4); 00136 00137 skip_bits_long(gb, 4 + 11 * 8); 00138 00139 return 0; 00140 } 00141 00142 typedef struct MLPParseContext 00143 { 00144 ParseContext pc; 00145 00146 int bytes_left; 00147 00148 int in_sync; 00149 00150 int num_substreams; 00151 } MLPParseContext; 00152 00153 static av_cold int mlp_init(AVCodecParserContext *s) 00154 { 00155 ff_mlp_init_crc(); 00156 return 0; 00157 } 00158 00159 static int mlp_parse(AVCodecParserContext *s, 00160 AVCodecContext *avctx, 00161 const uint8_t **poutbuf, int *poutbuf_size, 00162 const uint8_t *buf, int buf_size) 00163 { 00164 MLPParseContext *mp = s->priv_data; 00165 int sync_present; 00166 uint8_t parity_bits; 00167 int next; 00168 int i, p = 0; 00169 00170 *poutbuf_size = 0; 00171 if (buf_size == 0) 00172 return 0; 00173 00174 if (!mp->in_sync) { 00175 // Not in sync - find a major sync header 00176 00177 for (i = 0; i < buf_size; i++) { 00178 mp->pc.state = (mp->pc.state << 8) | buf[i]; 00179 if ((mp->pc.state & 0xfffffffe) == 0xf8726fba && 00180 // ignore if we do not have the data for the start of header 00181 mp->pc.index + i >= 7) { 00182 mp->in_sync = 1; 00183 mp->bytes_left = 0; 00184 break; 00185 } 00186 } 00187 00188 if (!mp->in_sync) { 00189 ff_combine_frame(&mp->pc, END_NOT_FOUND, &buf, &buf_size); 00190 return buf_size; 00191 } 00192 00193 ff_combine_frame(&mp->pc, i - 7, &buf, &buf_size); 00194 00195 return i - 7; 00196 } 00197 00198 if (mp->bytes_left == 0) { 00199 // Find length of this packet 00200 00201 /* Copy overread bytes from last frame into buffer. */ 00202 for(; mp->pc.overread>0; mp->pc.overread--) { 00203 mp->pc.buffer[mp->pc.index++]= mp->pc.buffer[mp->pc.overread_index++]; 00204 } 00205 00206 if (mp->pc.index + buf_size < 2) { 00207 ff_combine_frame(&mp->pc, END_NOT_FOUND, &buf, &buf_size); 00208 return buf_size; 00209 } 00210 00211 mp->bytes_left = ((mp->pc.index > 0 ? mp->pc.buffer[0] : buf[0]) << 8) 00212 | (mp->pc.index > 1 ? mp->pc.buffer[1] : buf[1-mp->pc.index]); 00213 mp->bytes_left = (mp->bytes_left & 0xfff) * 2; 00214 mp->bytes_left -= mp->pc.index; 00215 } 00216 00217 next = (mp->bytes_left > buf_size) ? END_NOT_FOUND : mp->bytes_left; 00218 00219 if (ff_combine_frame(&mp->pc, next, &buf, &buf_size) < 0) { 00220 mp->bytes_left -= buf_size; 00221 return buf_size; 00222 } 00223 00224 mp->bytes_left = 0; 00225 00226 sync_present = (AV_RB32(buf + 4) & 0xfffffffe) == 0xf8726fba; 00227 00228 if (!sync_present) { 00229 /* The first nibble of a frame is a parity check of the 4-byte 00230 * access unit header and all the 2- or 4-byte substream headers. */ 00231 // Only check when this isn't a sync frame - syncs have a checksum. 00232 00233 parity_bits = 0; 00234 for (i = -1; i < mp->num_substreams; i++) { 00235 parity_bits ^= buf[p++]; 00236 parity_bits ^= buf[p++]; 00237 00238 if (i < 0 || buf[p-2] & 0x80) { 00239 parity_bits ^= buf[p++]; 00240 parity_bits ^= buf[p++]; 00241 } 00242 } 00243 00244 if ((((parity_bits >> 4) ^ parity_bits) & 0xF) != 0xF) { 00245 av_log(avctx, AV_LOG_INFO, "mlpparse: Parity check failed.\n"); 00246 goto lost_sync; 00247 } 00248 } else { 00249 GetBitContext gb; 00250 MLPHeaderInfo mh; 00251 00252 init_get_bits(&gb, buf + 4, (buf_size - 4) << 3); 00253 if (ff_mlp_read_major_sync(avctx, &mh, &gb) < 0) 00254 goto lost_sync; 00255 00256 avctx->bits_per_raw_sample = mh.group1_bits; 00257 if (avctx->bits_per_raw_sample > 16) 00258 avctx->sample_fmt = SAMPLE_FMT_S32; 00259 else 00260 avctx->sample_fmt = SAMPLE_FMT_S16; 00261 avctx->sample_rate = mh.group1_samplerate; 00262 avctx->frame_size = mh.access_unit_size; 00263 00264 if (mh.stream_type == 0xbb) { 00265 /* MLP stream */ 00266 avctx->channels = mlp_channels[mh.channels_mlp]; 00267 } else { /* mh.stream_type == 0xba */ 00268 /* TrueHD stream */ 00269 if (mh.channels_thd_stream2) 00270 avctx->channels = truehd_channels(mh.channels_thd_stream2); 00271 else 00272 avctx->channels = truehd_channels(mh.channels_thd_stream1); 00273 } 00274 00275 if (!mh.is_vbr) /* Stream is CBR */ 00276 avctx->bit_rate = mh.peak_bitrate; 00277 00278 mp->num_substreams = mh.num_substreams; 00279 } 00280 00281 *poutbuf = buf; 00282 *poutbuf_size = buf_size; 00283 00284 return next; 00285 00286 lost_sync: 00287 mp->in_sync = 0; 00288 return 1; 00289 } 00290 00291 AVCodecParser mlp_parser = { 00292 { CODEC_ID_MLP, CODEC_ID_TRUEHD }, 00293 sizeof(MLPParseContext), 00294 mlp_init, 00295 mlp_parse, 00296 ff_parse_close, 00297 };