Codebase list squeezelite / 67e437c
faad and mad gapless improvements - attempt to deal with case where tracks are skipped and hence number of samples in header is wrong - aac case recalcuate samples from stts atom - mad detect early end and trim off padding (based on patches from Wouter Ellenbroek) Adrian Smith 10 years ago
2 changed file(s) with 35 addition(s) and 1 deletion(s). Raw diff Collapse all Expand all
3838 void *stsc;
3939 u32_t skip;
4040 u64_t samples;
41 u64_t sttssamples;
4142 bool empty;
4243 struct chunk_table *chunkinfo;
4344 // faad symbols to be dynamically loaded
140141 LOG_DEBUG("playable aac track: %u", trak);
141142 play = trak;
142143 }
144 }
145
146 // extract the total number of samples from stts
147 if (!strcmp(type, "stts") && bytes > len) {
148 u32_t i;
149 u8_t *ptr = streambuf->readp + 12;
150 u32_t entries = unpackN((u32_t *)ptr);
151 ptr += 4;
152 for (i = 0; i < entries; ++i) {
153 u32_t count = unpackN((u32_t *)ptr);
154 u32_t size = unpackN((u32_t *)(ptr + 4));
155 a->sttssamples += count * size;
156 ptr += 8;
157 }
158 LOG_DEBUG("total number of samples contained in stts: " FMT_u64, a->sttssamples);
143159 }
144160
145161 // stash sample to chunk info, assume it comes before stco
241257 u32_t b, c; u64_t d;
242258 if (sscanf((const char *)(ptr + 16), "%x %x %x " FMT_x64, &b, &b, &c, &d) == 4) {
243259 LOG_DEBUG("iTunSMPB start: %u end: %u samples: " FMT_u64, b, c, d);
260 if (a->sttssamples && a->sttssamples < b + c + d) {
261 LOG_DEBUG("reducing samples as stts count is less");
262 d = a->sttssamples - (b + c);
263 }
244264 a->skip = b;
245265 a->samples = d;
246266 }
266286 _buf_inc_readp(streambuf, consume);
267287 a->pos += consume;
268288 bytes -= consume;
269 } else if (!(!strcmp(type, "esds") || !strcmp(type, "stsc") || !strcmp(type, "stco"))) {
289 } else if ( !(!strcmp(type, "esds") || !strcmp(type, "stts") || !strcmp(type, "stsc") ||
290 !strcmp(type, "stco") || !strcmp(type, "----")) ) {
270291 LOG_DEBUG("type: %s len: %u consume: %u - partial consume: %u", type, len, consume, bytes);
271292 _buf_inc_readp(streambuf, bytes);
272293 a->pos += bytes;
521542 a->stsc = NULL;
522543 a->skip = 0;
523544 a->samples = 0;
545 a->sttssamples = 0;
524546 a->empty = false;
525547
526548 if (a->hAac) {
3636 bool checkgapless;
3737 u32_t skip;
3838 u64_t samples;
39 u32_t padding;
3940 // mad symbols to be dynamically loaded
4041 void (* mad_stream_init)(struct mad_stream *);
4142 void (* mad_frame_init)(struct mad_frame *);
127128 // add one frame to initial skip for this (empty) frame
128129 m->skip = enc_delay + 1152;
129130 m->samples = frame_count * 1152 - enc_delay - enc_padding;
131 m->padding = enc_padding;
130132
131133 LOG_INFO("gapless: skip: %u samples: " FMT_u64 " delay: %u padding: %u", m->skip, m->samples, enc_delay, enc_padding);
132134 }
238240 frames = (size_t)m->samples;
239241 }
240242 m->samples -= frames;
243 if (m->samples > 0 && eos && !(m->stream.next_frame[0] == 0xff && (m->stream.next_frame[1] & 0xf0) == 0xf0)) {
244 // this is the last frame to be decoded, but more samples expected so we must have skipped, remove padding
245 LOG_DEBUG("gapless: early end - trimming padding from end");
246 if (frames >= m->padding) {
247 frames -= m->padding;
248 } else {
249 frames = 0;
250 }
251 m->samples = 0;
252 }
241253 }
242254
243255 LOG_SDEBUG("write %u frames", frames);