00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00035 #include "libavutil/crc.h"
00036 #include "libavutil/fifo.h"
00037 #include "bytestream.h"
00038 #include "parser.h"
00039 #include "flac.h"
00040
00042 #define FLAC_MAX_SEQUENTIAL_HEADERS 3
00043
00044 #define FLAC_MIN_HEADERS 10
00045
00046 #define FLAC_AVG_FRAME_SIZE 8192
00047
00049 #define FLAC_HEADER_BASE_SCORE 10
00050 #define FLAC_HEADER_CHANGED_PENALTY 7
00051 #define FLAC_HEADER_CRC_FAIL_PENALTY 50
00052 #define FLAC_HEADER_NOT_PENALIZED_YET 100000
00053 #define FLAC_HEADER_NOT_SCORED_YET -100000
00054
00056 #define MAX_FRAME_HEADER_SIZE 16
00057
00058 typedef struct FLACHeaderMarker {
00059 int offset;
00060 int *link_penalty;
00062 int max_score;
00064 FLACFrameInfo fi;
00065 struct FLACHeaderMarker *next;
00068 struct FLACHeaderMarker *best_child;
00071 } FLACHeaderMarker;
00072
00073 typedef struct FLACParseContext {
00074 AVCodecParserContext *pc;
00075 AVCodecContext *avctx;
00076 FLACHeaderMarker *headers;
00078 FLACHeaderMarker *best_header;
00079 int nb_headers_found;
00081 int nb_headers_buffered;
00082 int best_header_valid;
00084 AVFifoBuffer *fifo_buf;
00086 int end_padded;
00087 uint8_t *wrap_buf;
00088 int wrap_buf_allocated_size;
00089 } FLACParseContext;
00090
00091 static int frame_header_is_valid(AVCodecContext *avctx, const uint8_t *buf,
00092 FLACFrameInfo *fi)
00093 {
00094 GetBitContext gb;
00095 init_get_bits(&gb, buf, MAX_FRAME_HEADER_SIZE * 8);
00096 return !ff_flac_decode_frame_header(avctx, &gb, fi, 127);
00097 }
00098
00112 static uint8_t* flac_fifo_read_wrap(FLACParseContext *fpc, int offset, int len,
00113 uint8_t** wrap_buf, int* allocated_size)
00114 {
00115 AVFifoBuffer *f = fpc->fifo_buf;
00116 uint8_t *start = f->rptr + offset;
00117 uint8_t *tmp_buf;
00118
00119 if (start >= f->end)
00120 start -= f->end - f->buffer;
00121 if (f->end - start >= len)
00122 return start;
00123
00124 tmp_buf = av_fast_realloc(*wrap_buf, allocated_size, len);
00125
00126 if (!tmp_buf) {
00127 av_log(fpc->avctx, AV_LOG_ERROR,
00128 "couldn't reallocate wrap buffer of size %d", len);
00129 return NULL;
00130 }
00131 *wrap_buf = tmp_buf;
00132 do {
00133 int seg_len = FFMIN(f->end - start, len);
00134 memcpy(tmp_buf, start, seg_len);
00135 tmp_buf = (uint8_t*)tmp_buf + seg_len;
00136
00137
00138 start += seg_len - (f->end - f->buffer);
00139 len -= seg_len;
00140 } while (len > 0);
00141
00142 return *wrap_buf;
00143 }
00144
00152 static uint8_t* flac_fifo_read(FLACParseContext *fpc, int offset, int *len)
00153 {
00154 AVFifoBuffer *f = fpc->fifo_buf;
00155 uint8_t *start = f->rptr + offset;
00156
00157 if (start >= f->end)
00158 start -= f->end - f->buffer;
00159 *len = FFMIN(*len, f->end - start);
00160 return start;
00161 }
00162
00163 static int find_headers_search_validate(FLACParseContext *fpc, int offset)
00164 {
00165 FLACFrameInfo fi;
00166 uint8_t *header_buf;
00167 int size = 0;
00168 header_buf = flac_fifo_read_wrap(fpc, offset,
00169 MAX_FRAME_HEADER_SIZE,
00170 &fpc->wrap_buf,
00171 &fpc->wrap_buf_allocated_size);
00172 if (frame_header_is_valid(fpc->avctx, header_buf, &fi)) {
00173 FLACHeaderMarker **end_handle = &fpc->headers;
00174 int i;
00175
00176 size = 0;
00177 while (*end_handle) {
00178 end_handle = &(*end_handle)->next;
00179 size++;
00180 }
00181
00182 *end_handle = av_mallocz(sizeof(FLACHeaderMarker));
00183 if (!*end_handle) {
00184 av_log(fpc->avctx, AV_LOG_ERROR,
00185 "couldn't allocate FLACHeaderMarker\n");
00186 return AVERROR(ENOMEM);
00187 }
00188 (*end_handle)->fi = fi;
00189 (*end_handle)->offset = offset;
00190 (*end_handle)->link_penalty = av_malloc(sizeof(int) *
00191 FLAC_MAX_SEQUENTIAL_HEADERS);
00192 for (i = 0; i < FLAC_MAX_SEQUENTIAL_HEADERS; i++)
00193 (*end_handle)->link_penalty[i] = FLAC_HEADER_NOT_PENALIZED_YET;
00194
00195 fpc->nb_headers_found++;
00196 size++;
00197 }
00198 return size;
00199 }
00200
00201 static int find_headers_search(FLACParseContext *fpc, uint8_t *buf, int buf_size,
00202 int search_start)
00203
00204 {
00205 int size = 0, mod_offset = (buf_size - 1) % 4, i, j;
00206 uint32_t x;
00207
00208 for (i = 0; i < mod_offset; i++) {
00209 if ((AV_RB16(buf + i) & 0xFFFE) == 0xFFF8)
00210 size = find_headers_search_validate(fpc, search_start + i);
00211 }
00212
00213 for (; i < buf_size - 1; i += 4) {
00214 x = AV_RB32(buf + i);
00215 if (((x & ~(x + 0x01010101)) & 0x80808080)) {
00216 for (j = 0; j < 4; j++) {
00217 if ((AV_RB16(buf + i + j) & 0xFFFE) == 0xFFF8)
00218 size = find_headers_search_validate(fpc, search_start + i + j);
00219 }
00220 }
00221 }
00222 return size;
00223 }
00224
00225 static int find_new_headers(FLACParseContext *fpc, int search_start)
00226 {
00227 FLACHeaderMarker *end;
00228 int search_end, size = 0, read_len, temp;
00229 uint8_t *buf;
00230 fpc->nb_headers_found = 0;
00231
00232
00233 search_end = av_fifo_size(fpc->fifo_buf) - (MAX_FRAME_HEADER_SIZE - 1);
00234 read_len = search_end - search_start + 1;
00235 buf = flac_fifo_read(fpc, search_start, &read_len);
00236 size = find_headers_search(fpc, buf, read_len, search_start);
00237 search_start += read_len - 1;
00238
00239
00240 if (search_start != search_end) {
00241 uint8_t wrap[2];
00242
00243 wrap[0] = buf[read_len - 1];
00244 read_len = search_end - search_start + 1;
00245
00246
00247 buf = flac_fifo_read(fpc, search_start + 1, &read_len);
00248 wrap[1] = buf[0];
00249
00250 if ((AV_RB16(wrap) & 0xFFFE) == 0xFFF8) {
00251 temp = find_headers_search_validate(fpc, search_start);
00252 size = FFMAX(size, temp);
00253 }
00254 search_start++;
00255
00256
00257 temp = find_headers_search(fpc, buf, read_len, search_start);
00258 size = FFMAX(size, temp);
00259 search_start += read_len - 1;
00260 }
00261
00262
00263 if (!size && fpc->headers)
00264 for (end = fpc->headers; end; end = end->next)
00265 size++;
00266 return size;
00267 }
00268
00269 static int check_header_mismatch(FLACParseContext *fpc,
00270 FLACHeaderMarker *header,
00271 FLACHeaderMarker *child,
00272 int log_level_offset)
00273 {
00274 FLACFrameInfo *header_fi = &header->fi, *child_fi = &child->fi;
00275 int deduction = 0, deduction_expected = 0, i;
00276 if (child_fi->samplerate != header_fi->samplerate) {
00277 deduction += FLAC_HEADER_CHANGED_PENALTY;
00278 av_log(fpc->avctx, AV_LOG_WARNING + log_level_offset,
00279 "sample rate change detected in adjacent frames\n");
00280 }
00281 if (child_fi->bps != header_fi->bps) {
00282 deduction += FLAC_HEADER_CHANGED_PENALTY;
00283 av_log(fpc->avctx, AV_LOG_WARNING + log_level_offset,
00284 "bits per sample change detected in adjacent frames\n");
00285 }
00286 if (child_fi->is_var_size != header_fi->is_var_size) {
00287
00288 deduction += FLAC_HEADER_BASE_SCORE;
00289 av_log(fpc->avctx, AV_LOG_WARNING + log_level_offset,
00290 "blocking strategy change detected in adjacent frames\n");
00291 }
00292 if (child_fi->channels != header_fi->channels) {
00293 deduction += FLAC_HEADER_CHANGED_PENALTY;
00294 av_log(fpc->avctx, AV_LOG_WARNING + log_level_offset,
00295 "number of channels change detected in adjacent frames\n");
00296 }
00297
00298 if ((child_fi->frame_or_sample_num - header_fi->frame_or_sample_num
00299 != header_fi->blocksize) &&
00300 (child_fi->frame_or_sample_num
00301 != header_fi->frame_or_sample_num + 1)) {
00302 FLACHeaderMarker *curr;
00303 int expected_frame_num, expected_sample_num;
00304
00305
00306
00307 expected_frame_num = expected_sample_num = header_fi->frame_or_sample_num;
00308 curr = header;
00309 while (curr != child) {
00310
00311 for (i = 0; i < FLAC_MAX_SEQUENTIAL_HEADERS; i++) {
00312 if (curr->link_penalty[i] < FLAC_HEADER_CRC_FAIL_PENALTY) {
00313 expected_frame_num++;
00314 expected_sample_num += curr->fi.blocksize;
00315 break;
00316 }
00317 }
00318 curr = curr->next;
00319 }
00320
00321 if (expected_frame_num == child_fi->frame_or_sample_num ||
00322 expected_sample_num == child_fi->frame_or_sample_num)
00323 deduction_expected = deduction ? 0 : 1;
00324
00325 deduction += FLAC_HEADER_CHANGED_PENALTY;
00326 av_log(fpc->avctx, AV_LOG_WARNING + log_level_offset,
00327 "sample/frame number mismatch in adjacent frames\n");
00328 }
00329
00330
00331 if (deduction && !deduction_expected) {
00332 FLACHeaderMarker *curr;
00333 int read_len;
00334 uint8_t *buf;
00335 uint32_t crc = 1;
00336 int inverted_test = 0;
00337
00338
00339
00340 curr = header->next;
00341 for (i = 0; i < FLAC_MAX_SEQUENTIAL_HEADERS && curr != child; i++)
00342 curr = curr->next;
00343
00344 if (header->link_penalty[i] < FLAC_HEADER_CRC_FAIL_PENALTY ||
00345 header->link_penalty[i] == FLAC_HEADER_NOT_PENALIZED_YET) {
00346 FLACHeaderMarker *start, *end;
00347
00348
00349
00350 start = header;
00351 end = child;
00352 if (i > 0 &&
00353 header->link_penalty[i - 1] >= FLAC_HEADER_CRC_FAIL_PENALTY) {
00354 while (start->next != child)
00355 start = start->next;
00356 inverted_test = 1;
00357 } else if (i > 0 &&
00358 header->next->link_penalty[i-1] >=
00359 FLAC_HEADER_CRC_FAIL_PENALTY ) {
00360 end = header->next;
00361 inverted_test = 1;
00362 }
00363
00364 read_len = end->offset - start->offset;
00365 buf = flac_fifo_read(fpc, start->offset, &read_len);
00366 crc = av_crc(av_crc_get_table(AV_CRC_16_ANSI), 0, buf, read_len);
00367 read_len = (end->offset - start->offset) - read_len;
00368
00369 if (read_len) {
00370 buf = flac_fifo_read(fpc, end->offset - read_len, &read_len);
00371 crc = av_crc(av_crc_get_table(AV_CRC_16_ANSI), crc, buf, read_len);
00372 }
00373 }
00374
00375 if (!crc ^ !inverted_test) {
00376 deduction += FLAC_HEADER_CRC_FAIL_PENALTY;
00377 av_log(fpc->avctx, AV_LOG_WARNING + log_level_offset,
00378 "crc check failed from offset %i (frame %"PRId64") to %i (frame %"PRId64")\n",
00379 header->offset, header_fi->frame_or_sample_num,
00380 child->offset, child_fi->frame_or_sample_num);
00381 }
00382 }
00383 return deduction;
00384 }
00385
00396 static int score_header(FLACParseContext *fpc, FLACHeaderMarker *header)
00397 {
00398 FLACHeaderMarker *child;
00399 int dist = 0;
00400 int child_score;
00401
00402 if (header->max_score != FLAC_HEADER_NOT_SCORED_YET)
00403 return header->max_score;
00404
00405 header->max_score = FLAC_HEADER_BASE_SCORE;
00406
00407
00408 child = header->next;
00409 for (dist = 0; dist < FLAC_MAX_SEQUENTIAL_HEADERS && child; dist++) {
00410
00411
00412 if (header->link_penalty[dist] == FLAC_HEADER_NOT_PENALIZED_YET) {
00413 header->link_penalty[dist] = check_header_mismatch(fpc, header,
00414 child, AV_LOG_DEBUG);
00415 }
00416 child_score = score_header(fpc, child) - header->link_penalty[dist];
00417
00418 if (FLAC_HEADER_BASE_SCORE + child_score > header->max_score) {
00419
00420 header->best_child = child;
00421 header->max_score = FLAC_HEADER_BASE_SCORE + child_score;
00422 }
00423 child = child->next;
00424 }
00425
00426 return header->max_score;
00427 }
00428
00429 static void score_sequences(FLACParseContext *fpc)
00430 {
00431 FLACHeaderMarker *curr;
00432 int best_score = FLAC_HEADER_NOT_SCORED_YET;
00433
00434 for (curr = fpc->headers; curr; curr = curr->next)
00435 curr->max_score = FLAC_HEADER_NOT_SCORED_YET;
00436
00437
00438 for (curr = fpc->headers; curr; curr = curr->next) {
00439 if (score_header(fpc, curr) > best_score) {
00440 fpc->best_header = curr;
00441 best_score = curr->max_score;
00442 }
00443 }
00444 }
00445
00446 static int get_best_header(FLACParseContext* fpc, const uint8_t **poutbuf,
00447 int *poutbuf_size)
00448 {
00449 FLACHeaderMarker *header = fpc->best_header;
00450 FLACHeaderMarker *child = header->best_child;
00451 if (!child) {
00452 *poutbuf_size = av_fifo_size(fpc->fifo_buf) - header->offset;
00453 } else {
00454 *poutbuf_size = child->offset - header->offset;
00455
00456
00457 check_header_mismatch(fpc, header, child, 0);
00458 }
00459
00460 fpc->avctx->sample_rate = header->fi.samplerate;
00461 fpc->avctx->channels = header->fi.channels;
00462 fpc->pc->duration = header->fi.blocksize;
00463 *poutbuf = flac_fifo_read_wrap(fpc, header->offset, *poutbuf_size,
00464 &fpc->wrap_buf,
00465 &fpc->wrap_buf_allocated_size);
00466
00467 fpc->best_header_valid = 0;
00468
00469
00470 if (child)
00471 return child->offset - av_fifo_size(fpc->fifo_buf);
00472 return 0;
00473 }
00474
00475 static int flac_parse(AVCodecParserContext *s, AVCodecContext *avctx,
00476 const uint8_t **poutbuf, int *poutbuf_size,
00477 const uint8_t *buf, int buf_size)
00478 {
00479 FLACParseContext *fpc = s->priv_data;
00480 FLACHeaderMarker *curr;
00481 int nb_headers;
00482 const uint8_t *read_end = buf;
00483 const uint8_t *read_start = buf;
00484
00485 if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) {
00486 FLACFrameInfo fi;
00487 if (frame_header_is_valid(avctx, buf, &fi))
00488 s->duration = fi.blocksize;
00489 *poutbuf = buf;
00490 *poutbuf_size = buf_size;
00491 return buf_size;
00492 }
00493
00494 fpc->avctx = avctx;
00495 if (fpc->best_header_valid)
00496 return get_best_header(fpc, poutbuf, poutbuf_size);
00497
00498
00499 if (fpc->best_header && fpc->best_header->best_child) {
00500 FLACHeaderMarker *temp;
00501 FLACHeaderMarker *best_child = fpc->best_header->best_child;
00502
00503
00504 for (curr = fpc->headers; curr != best_child; curr = temp) {
00505 if (curr != fpc->best_header) {
00506 av_log(avctx, AV_LOG_DEBUG,
00507 "dropping low score %i frame header from offset %i to %i\n",
00508 curr->max_score, curr->offset, curr->next->offset);
00509 }
00510 temp = curr->next;
00511 av_freep(&curr->link_penalty);
00512 av_free(curr);
00513 fpc->nb_headers_buffered--;
00514 }
00515
00516 av_fifo_drain(fpc->fifo_buf, best_child->offset);
00517
00518
00519 for (curr = best_child->next; curr; curr = curr->next)
00520 curr->offset -= best_child->offset;
00521
00522 fpc->nb_headers_buffered--;
00523 best_child->offset = 0;
00524 fpc->headers = best_child;
00525 if (fpc->nb_headers_buffered >= FLAC_MIN_HEADERS) {
00526 fpc->best_header = best_child;
00527 return get_best_header(fpc, poutbuf, poutbuf_size);
00528 }
00529 fpc->best_header = NULL;
00530 } else if (fpc->best_header) {
00531
00532 FLACHeaderMarker *temp;
00533
00534 for (curr = fpc->headers; curr != fpc->best_header; curr = temp) {
00535 temp = curr->next;
00536 av_freep(&curr->link_penalty);
00537 av_free(curr);
00538 }
00539 fpc->headers = fpc->best_header->next;
00540 av_freep(&fpc->best_header->link_penalty);
00541 av_freep(&fpc->best_header);
00542 }
00543
00544
00545 while ((buf && read_end < buf + buf_size &&
00546 fpc->nb_headers_buffered < FLAC_MIN_HEADERS)
00547 || (!buf && !fpc->end_padded)) {
00548 int start_offset;
00549
00550
00551 if (!buf) {
00552 fpc->end_padded = 1;
00553 buf_size = MAX_FRAME_HEADER_SIZE;
00554 read_end = read_start + MAX_FRAME_HEADER_SIZE;
00555 } else {
00556
00557
00558 int nb_desired = FLAC_MIN_HEADERS - fpc->nb_headers_buffered + 1;
00559 read_end = read_end + FFMIN(buf + buf_size - read_end,
00560 nb_desired * FLAC_AVG_FRAME_SIZE);
00561 }
00562
00563
00564 if ( av_fifo_space(fpc->fifo_buf) < read_end - read_start
00565 && av_fifo_realloc2(fpc->fifo_buf, (read_end - read_start) + 2*av_fifo_size(fpc->fifo_buf)) < 0) {
00566 av_log(avctx, AV_LOG_ERROR,
00567 "couldn't reallocate buffer of size %td\n",
00568 (read_end - read_start) + av_fifo_size(fpc->fifo_buf));
00569 goto handle_error;
00570 }
00571
00572 if (buf) {
00573 av_fifo_generic_write(fpc->fifo_buf, (void*) read_start,
00574 read_end - read_start, NULL);
00575 } else {
00576 int8_t pad[MAX_FRAME_HEADER_SIZE] = { 0 };
00577 av_fifo_generic_write(fpc->fifo_buf, (void*) pad, sizeof(pad), NULL);
00578 }
00579
00580
00581 start_offset = av_fifo_size(fpc->fifo_buf) -
00582 ((read_end - read_start) + (MAX_FRAME_HEADER_SIZE - 1));
00583 start_offset = FFMAX(0, start_offset);
00584 nb_headers = find_new_headers(fpc, start_offset);
00585
00586 if (nb_headers < 0) {
00587 av_log(avctx, AV_LOG_ERROR,
00588 "find_new_headers couldn't allocate FLAC header\n");
00589 goto handle_error;
00590 }
00591
00592 fpc->nb_headers_buffered = nb_headers;
00593
00594 if (!fpc->end_padded && fpc->nb_headers_buffered < FLAC_MIN_HEADERS) {
00595 if (buf && read_end < buf + buf_size) {
00596 read_start = read_end;
00597 continue;
00598 } else {
00599 goto handle_error;
00600 }
00601 }
00602
00603
00604 if (fpc->end_padded || fpc->nb_headers_found)
00605 score_sequences(fpc);
00606
00607
00608 if (fpc->end_padded) {
00609 int warp = fpc->fifo_buf->wptr - fpc->fifo_buf->buffer < MAX_FRAME_HEADER_SIZE;
00610
00611 fpc->fifo_buf->wptr -= MAX_FRAME_HEADER_SIZE;
00612 fpc->fifo_buf->wndx -= MAX_FRAME_HEADER_SIZE;
00613 if (warp) {
00614 fpc->fifo_buf->wptr += fpc->fifo_buf->end -
00615 fpc->fifo_buf->buffer;
00616 }
00617 buf_size = 0;
00618 read_start = read_end = NULL;
00619 }
00620 }
00621
00622 curr = fpc->headers;
00623 for (curr = fpc->headers; curr; curr = curr->next)
00624 if (!fpc->best_header || curr->max_score > fpc->best_header->max_score)
00625 fpc->best_header = curr;
00626
00627 if (fpc->best_header) {
00628 fpc->best_header_valid = 1;
00629 if (fpc->best_header->offset > 0) {
00630
00631 av_log(avctx, AV_LOG_DEBUG, "Junk frame till offset %i\n",
00632 fpc->best_header->offset);
00633
00634
00635 s->duration = 0;
00636 *poutbuf_size = fpc->best_header->offset;
00637 *poutbuf = flac_fifo_read_wrap(fpc, 0, *poutbuf_size,
00638 &fpc->wrap_buf,
00639 &fpc->wrap_buf_allocated_size);
00640 return buf_size ? (read_end - buf) : (fpc->best_header->offset -
00641 av_fifo_size(fpc->fifo_buf));
00642 }
00643 if (!buf_size)
00644 return get_best_header(fpc, poutbuf, poutbuf_size);
00645 }
00646
00647 handle_error:
00648 *poutbuf = NULL;
00649 *poutbuf_size = 0;
00650 return read_end - buf;
00651 }
00652
00653 static int flac_parse_init(AVCodecParserContext *c)
00654 {
00655 FLACParseContext *fpc = c->priv_data;
00656 fpc->pc = c;
00657
00658
00659 fpc->fifo_buf = av_fifo_alloc(FLAC_AVG_FRAME_SIZE * (FLAC_MIN_HEADERS + 3));
00660 return 0;
00661 }
00662
00663 static void flac_parse_close(AVCodecParserContext *c)
00664 {
00665 FLACParseContext *fpc = c->priv_data;
00666 FLACHeaderMarker *curr = fpc->headers, *temp;
00667
00668 while (curr) {
00669 temp = curr->next;
00670 av_freep(&curr->link_penalty);
00671 av_free(curr);
00672 curr = temp;
00673 }
00674 av_fifo_free(fpc->fifo_buf);
00675 av_free(fpc->wrap_buf);
00676 }
00677
00678 AVCodecParser ff_flac_parser = {
00679 .codec_ids = { AV_CODEC_ID_FLAC },
00680 .priv_data_size = sizeof(FLACParseContext),
00681 .parser_init = flac_parse_init,
00682 .parser_parse = flac_parse,
00683 .parser_close = flac_parse_close,
00684 };