00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00027 #include "tak.h"
00028 #include "parser.h"
00029
00030 typedef struct TAKParseContext {
00031 ParseContext pc;
00032 TAKStreamInfo ti;
00033 int index;
00034 } TAKParseContext;
00035
00036 static av_cold int tak_init(AVCodecParserContext *s)
00037 {
00038 ff_tak_init_crc();
00039 return 0;
00040 }
00041
00042 static int tak_parse(AVCodecParserContext *s, AVCodecContext *avctx,
00043 const uint8_t **poutbuf, int *poutbuf_size,
00044 const uint8_t *buf, int buf_size)
00045 {
00046 TAKParseContext *t = s->priv_data;
00047 ParseContext *pc = &t->pc;
00048 int next = END_NOT_FOUND;
00049 GetBitContext gb;
00050 int consumed = 0;
00051 int needed = buf_size ? TAK_MAX_FRAME_HEADER_BYTES : 8;
00052
00053 if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) {
00054 TAKStreamInfo ti;
00055 init_get_bits(&gb, buf, buf_size);
00056 if (!ff_tak_decode_frame_header(avctx, &gb, &ti, 127))
00057 s->duration = t->ti.last_frame_samples ? t->ti.last_frame_samples
00058 : t->ti.frame_samples;
00059 *poutbuf = buf;
00060 *poutbuf_size = buf_size;
00061 return buf_size;
00062 }
00063
00064 while (buf_size || t->index + needed <= pc->index) {
00065 if (buf_size && t->index + TAK_MAX_FRAME_HEADER_BYTES > pc->index) {
00066 int tmp_buf_size = FFMIN(2 * TAK_MAX_FRAME_HEADER_BYTES,
00067 buf_size);
00068 const uint8_t *tmp_buf = buf;
00069
00070 if (ff_combine_frame(pc, END_NOT_FOUND, &tmp_buf, &tmp_buf_size) != -1)
00071 return AVERROR(ENOMEM);
00072 consumed += tmp_buf_size;
00073 buf += tmp_buf_size;
00074 buf_size -= tmp_buf_size;
00075 }
00076
00077 for (; t->index + needed <= pc->index; t->index++) {
00078 if (pc->buffer[ t->index ] == 0xFF &&
00079 pc->buffer[ t->index + 1 ] == 0xA0) {
00080 TAKStreamInfo ti;
00081
00082 init_get_bits(&gb, pc->buffer + t->index,
00083 8 * (pc->index - t->index));
00084 if (!ff_tak_decode_frame_header(avctx, &gb,
00085 pc->frame_start_found ? &ti : &t->ti, 127) &&
00086 !ff_tak_check_crc(pc->buffer + t->index,
00087 get_bits_count(&gb) / 8)) {
00088 if (!pc->frame_start_found) {
00089 pc->frame_start_found = 1;
00090 s->duration = t->ti.last_frame_samples ?
00091 t->ti.last_frame_samples :
00092 t->ti.frame_samples;
00093 } else {
00094 pc->frame_start_found = 0;
00095 next = t->index - pc->index;
00096 t->index = 0;
00097 goto found;
00098 }
00099 }
00100 }
00101 }
00102 }
00103 found:
00104
00105 if (consumed && !buf_size && next == END_NOT_FOUND ||
00106 ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
00107 *poutbuf = NULL;
00108 *poutbuf_size = 0;
00109 return buf_size + consumed;
00110 }
00111
00112 if (next != END_NOT_FOUND) {
00113 next += consumed;
00114 pc->overread = FFMAX(0, -next);
00115 }
00116
00117 *poutbuf = buf;
00118 *poutbuf_size = buf_size;
00119 return next;
00120 }
00121
00122 AVCodecParser ff_tak_parser = {
00123 .codec_ids = { AV_CODEC_ID_TAK },
00124 .priv_data_size = sizeof(TAKParseContext),
00125 .parser_init = tak_init,
00126 .parser_parse = tak_parse,
00127 .parser_close = ff_parse_close,
00128 };