diff options
author | Mark Reid <mindmark@gmail.com> | 2016-02-13 21:44:32 -0800 |
---|---|---|
committer | Michael Niedermayer <michael@niedermayer.cc> | 2016-02-14 19:17:36 +0100 |
commit | 8395b6eeaa279cff5c1c5d2b2ddfd5be087ca3ee (patch) | |
tree | 1b5834e1adcacc81f73f312ed413bcb72076a3e6 | |
parent | b8bc6b14a556e11e3f6cb49ead9d21d9a769b7c8 (diff) | |
download | ffmpeg-8395b6eeaa279cff5c1c5d2b2ddfd5be087ca3ee.tar.gz |
libavcodec/dnxhd_parser: add parser and probe support raw 444 and dnxhr formats
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
-rw-r--r-- | libavcodec/dnxhd_parser.c | 7 | ||||
-rw-r--r-- | libavcodec/dnxhddata.c | 8 | ||||
-rw-r--r-- | libavcodec/dnxhddata.h | 18 | ||||
-rw-r--r-- | libavcodec/dnxhddec.c | 12 | ||||
-rw-r--r-- | libavformat/dnxhddec.c | 7 |
5 files changed, 36 insertions, 16 deletions
diff --git a/libavcodec/dnxhd_parser.c b/libavcodec/dnxhd_parser.c index fffb98fa48..033b8ee7e1 100644 --- a/libavcodec/dnxhd_parser.c +++ b/libavcodec/dnxhd_parser.c @@ -25,8 +25,7 @@ */ #include "parser.h" - -#define DNXHD_HEADER_PREFIX 0x000002800100 +#include "dnxhddata.h" typedef struct { ParseContext pc; @@ -47,7 +46,7 @@ static int dnxhd_find_frame_end(DNXHDParserContext *dctx, if (!pic_found) { for (i = 0; i < buf_size; i++) { state = (state << 8) | buf[i]; - if ((state & 0xffffffffff00LL) == DNXHD_HEADER_PREFIX) { + if (ff_dnxhd_check_header_prefix(state & 0xffffffffff00LL) != 0) { i++; pic_found = 1; interlaced = (state&2)>>1; /* byte following the 5-byte header prefix */ @@ -62,7 +61,7 @@ static int dnxhd_find_frame_end(DNXHDParserContext *dctx, return 0; for (; i < buf_size; i++) { state = (state << 8) | buf[i]; - if ((state & 0xffffffffff00LL) == DNXHD_HEADER_PREFIX) { + if (ff_dnxhd_check_header_prefix(state & 0xffffffffff00LL) != 0) { if (!interlaced || dctx->cur_field) { pc->frame_start_found = 0; pc->state64 = -1; diff --git a/libavcodec/dnxhddata.c b/libavcodec/dnxhddata.c index 82fbfdfa70..7d935a3f31 100644 --- a/libavcodec/dnxhddata.c +++ b/libavcodec/dnxhddata.c @@ -22,6 +22,7 @@ #include "avcodec.h" #include "dnxhddata.h" #include "libavutil/common.h" +#include "libavutil/intreadwrite.h" /* The quantization tables below are in zigzag order! */ @@ -1102,6 +1103,13 @@ int avpriv_dnxhd_get_interlaced(int cid) return ff_dnxhd_cid_table[i].flags & DNXHD_INTERLACED ? 1 : 0; } +uint64_t avpriv_dnxhd_parse_header_prefix(const uint8_t *buf) +{ + uint64_t prefix = AV_RB32(buf); + prefix = (prefix << 16) | buf[4] << 8; + return ff_dnxhd_check_header_prefix(prefix); +} + int ff_dnxhd_find_cid(AVCodecContext *avctx, int bit_depth) { int i, j; diff --git a/libavcodec/dnxhddata.h b/libavcodec/dnxhddata.h index d97388818d..3ae4683a6c 100644 --- a/libavcodec/dnxhddata.h +++ b/libavcodec/dnxhddata.h @@ -31,6 +31,12 @@ #define DNXHD_MBAFF (1<<1) #define DNXHD_444 (1<<2) +/** Frame headers, extra 0x00 added to end for parser */ +#define DNXHD_HEADER_INITIAL 0x000002800100 +#define DNXHD_HEADER_444 0x000002800200 +#define DNXHD_HEADER_HR1 0x000002800300 +#define DNXHD_HEADER_HR2 0x0000038C0300 + /** Indicate that a CIDEntry value must be read in the bitstream */ #define DNXHD_VARIABLE 0 @@ -59,7 +65,17 @@ int ff_dnxhd_get_cid_table(int cid); int ff_dnxhd_find_cid(AVCodecContext *avctx, int bit_depth); void ff_dnxhd_print_profiles(AVCodecContext *avctx, int loglevel); +static av_always_inline uint64_t ff_dnxhd_check_header_prefix(uint64_t prefix) +{ + if (prefix == DNXHD_HEADER_INITIAL || + prefix == DNXHD_HEADER_444 || + prefix == DNXHD_HEADER_HR1 || + prefix == DNXHD_HEADER_HR2) + return prefix; + return 0; +} + int avpriv_dnxhd_get_frame_size(int cid); int avpriv_dnxhd_get_interlaced(int cid); - +uint64_t avpriv_dnxhd_parse_header_prefix(const uint8_t *buf); #endif /* AVCODEC_DNXHDDATA_H */ diff --git a/libavcodec/dnxhddec.c b/libavcodec/dnxhddec.c index 5c09c64f8e..18080803fa 100644 --- a/libavcodec/dnxhddec.c +++ b/libavcodec/dnxhddec.c @@ -163,21 +163,17 @@ static int dnxhd_decode_header(DNXHDContext *ctx, AVFrame *frame, const uint8_t *buf, int buf_size, int first_field) { - static const uint8_t header_prefix[] = { 0x00, 0x00, 0x02, 0x80, 0x01 }; - static const uint8_t header_prefix444[] = { 0x00, 0x00, 0x02, 0x80, 0x02 }; - static const uint8_t header_prefixhr1[] = { 0x00, 0x00, 0x02, 0x80, 0x03 }; - static const uint8_t header_prefixhr2[] = { 0x00, 0x00, 0x03, 0x8C, 0x03 }; int i, cid, ret; int old_bit_depth = ctx->bit_depth, bitdepth; - + uint64_t header_prefix; if (buf_size < 0x280) { av_log(ctx->avctx, AV_LOG_ERROR, "buffer too small (%d < 640).\n", buf_size); return AVERROR_INVALIDDATA; } - if (memcmp(buf, header_prefix, 5) && memcmp(buf, header_prefix444, 5) && - memcmp(buf, header_prefixhr1, 5) && memcmp(buf, header_prefixhr2, 5)) { + header_prefix = avpriv_dnxhd_parse_header_prefix(buf); + if (header_prefix == 0) { av_log(ctx->avctx, AV_LOG_ERROR, "unknown header 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n", buf[0], buf[1], buf[2], buf[3], buf[4]); @@ -279,7 +275,7 @@ static int dnxhd_decode_header(DNXHDContext *ctx, AVFrame *frame, ctx->bit_depth, ctx->mbaff, ctx->act); // Newer format supports variable mb_scan_index sizes - if (!memcmp(buf, header_prefixhr2, 5)) { + if (header_prefix == DNXHD_HEADER_HR2) { ctx->data_offset = 0x170 + (ctx->mb_height << 2); } else { if (ctx->mb_height > 68 || diff --git a/libavformat/dnxhddec.c b/libavformat/dnxhddec.c index 37e52d54c2..48c890d185 100644 --- a/libavformat/dnxhddec.c +++ b/libavformat/dnxhddec.c @@ -23,21 +23,22 @@ #include "libavutil/intreadwrite.h" #include "avformat.h" #include "rawdec.h" +#include "libavcodec/dnxhddata.h" static int dnxhd_probe(AVProbeData *p) { - static const uint8_t header[] = {0x00,0x00,0x02,0x80,0x01}; int w, h, compression_id; if (p->buf_size < 0x2c) return 0; - if (memcmp(p->buf, header, 5)) + if (avpriv_dnxhd_parse_header_prefix(p->buf) == 0) return 0; h = AV_RB16(p->buf + 0x18); w = AV_RB16(p->buf + 0x1a); if (!w || !h) return 0; compression_id = AV_RB32(p->buf + 0x28); - if (compression_id < 1235 || compression_id > 1260) + if ((compression_id < 1235 || compression_id > 1260) && + (compression_id < 1270 || compression_id > 1274)) return 0; return AVPROBE_SCORE_MAX; } |