00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00027 #include "parser.h"
00028
00029 #define DNXHD_HEADER_PREFIX 0x000002800100
00030
00031 typedef struct {
00032 ParseContext pc;
00033 int interlaced;
00034 int cur_field;
00035 } DNXHDParserContext;
00036
00037 static int dnxhd_find_frame_end(DNXHDParserContext *dctx,
00038 const uint8_t *buf, int buf_size)
00039 {
00040 ParseContext *pc = &dctx->pc;
00041 uint64_t state = pc->state64;
00042 int pic_found = pc->frame_start_found;
00043 int i = 0;
00044 int interlaced = dctx->interlaced;
00045 int cur_field = dctx->cur_field;
00046
00047 if (!pic_found) {
00048 for (i = 0; i < buf_size; i++) {
00049 state = (state<<8) | buf[i];
00050 if ((state & 0xffffffffff00LL) == DNXHD_HEADER_PREFIX) {
00051 i++;
00052 pic_found = 1;
00053 interlaced = (state&2)>>1;
00054 cur_field = state&1;
00055 break;
00056 }
00057 }
00058 }
00059
00060 if (pic_found) {
00061 if (!buf_size)
00062 return 0;
00063 for (; i < buf_size; i++) {
00064 state = (state<<8) | buf[i];
00065 if ((state & 0xffffffffff00LL) == DNXHD_HEADER_PREFIX) {
00066 if (!interlaced || dctx->cur_field) {
00067 pc->frame_start_found = 0;
00068 pc->state64 = -1;
00069 dctx->interlaced = interlaced;
00070 dctx->cur_field = 0;
00071 return i-5;
00072 } else {
00073
00074 dctx->interlaced = interlaced = (state&2)>>1;
00075 dctx->cur_field = cur_field = state&1;
00076 }
00077 }
00078 }
00079 }
00080 pc->frame_start_found = pic_found;
00081 pc->state64 = state;
00082 dctx->interlaced = interlaced;
00083 dctx->cur_field = cur_field;
00084 return END_NOT_FOUND;
00085 }
00086
00087 static int dnxhd_parse(AVCodecParserContext *s,
00088 AVCodecContext *avctx,
00089 const uint8_t **poutbuf, int *poutbuf_size,
00090 const uint8_t *buf, int buf_size)
00091 {
00092 DNXHDParserContext *dctx = s->priv_data;
00093 ParseContext *pc = &dctx->pc;
00094 int next;
00095
00096 if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) {
00097 next = buf_size;
00098 } else {
00099 next = dnxhd_find_frame_end(dctx, buf, buf_size);
00100 if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
00101 *poutbuf = NULL;
00102 *poutbuf_size = 0;
00103 return buf_size;
00104 }
00105 }
00106 *poutbuf = buf;
00107 *poutbuf_size = buf_size;
00108 return next;
00109 }
00110
00111 AVCodecParser ff_dnxhd_parser = {
00112 .codec_ids = { CODEC_ID_DNXHD },
00113 .priv_data_size = sizeof(DNXHDParserContext),
00114 .parser_parse = dnxhd_parse,
00115 .parser_close = ff_parse_close,
00116 };