From: Christophe Gisquet <c.gisq...@ateme.com> This multiplies the framesize by 1.5 when there is alpha, for the CIDs allowing alpha. In addition, a new header is checked, because the alpha marking seems to be different. --- libavcodec/dnxhd_parser.c | 7 ++++--- libavcodec/dnxhddata.c | 17 ++++++++++++----- libavcodec/dnxhddata.h | 6 ++++-- libavcodec/dnxhdenc.c | 2 +- libavformat/mxfenc.c | 7 ++++--- 5 files changed, 25 insertions(+), 14 deletions(-)
diff --git a/libavcodec/dnxhd_parser.c b/libavcodec/dnxhd_parser.c index 63b4ff89e1..726fb2f5de 100644 --- a/libavcodec/dnxhd_parser.c +++ b/libavcodec/dnxhd_parser.c @@ -31,7 +31,7 @@ typedef struct { ParseContext pc; int cur_byte; int remaining; - int w, h; + int w, h, alpha; } DNXHDParserContext; static int dnxhd_find_frame_end(DNXHDParserContext *dctx, @@ -58,6 +58,7 @@ static int dnxhd_find_frame_end(DNXHDParserContext *dctx, if (pic_found && !dctx->remaining) { if (!buf_size) /* EOF considered as end of frame */ return 0; + dctx->alpha = (state >> 8) & 5; for (; i < buf_size; i++) { dctx->cur_byte++; state = (state << 8) | buf[i]; @@ -73,9 +74,9 @@ static int dnxhd_find_frame_end(DNXHDParserContext *dctx, if (cid <= 0) continue; - remaining = avpriv_dnxhd_get_frame_size(cid); + remaining = avpriv_dnxhd_get_frame_size(cid, dctx->alpha); if (remaining <= 0) { - remaining = avpriv_dnxhd_get_hr_frame_size(cid, dctx->w, dctx->h); + remaining = avpriv_dnxhd_get_hr_frame_size(cid, dctx->w, dctx->h, dctx->alpha); if (remaining <= 0) continue; } diff --git a/libavcodec/dnxhddata.c b/libavcodec/dnxhddata.c index 3a69a0f501..54663aa432 100644 --- a/libavcodec/dnxhddata.c +++ b/libavcodec/dnxhddata.c @@ -1083,15 +1083,19 @@ const CIDEntry *ff_dnxhd_get_cid_table(int cid) return NULL; } -int avpriv_dnxhd_get_frame_size(int cid) +int avpriv_dnxhd_get_frame_size(int cid, int alpha) { const CIDEntry *entry = ff_dnxhd_get_cid_table(cid); + int result; if (!entry) return -1; - return entry->frame_size; + result = entry->frame_size; + if (alpha && (entry->flags & DNXHD_444)) + result = (result * 3) >> 1; + return result; } -int avpriv_dnxhd_get_hr_frame_size(int cid, int w, int h) +int avpriv_dnxhd_get_hr_frame_size(int cid, int w, int h, int alpha) { const CIDEntry *entry = ff_dnxhd_get_cid_table(cid); int result; @@ -1099,8 +1103,11 @@ int avpriv_dnxhd_get_hr_frame_size(int cid, int w, int h) if (!entry) return -1; - result = ((h + 15) / 16) * ((w + 15) / 16) * (int64_t)entry->packet_scale.num / entry->packet_scale.den; - result = (result + 2048) / 4096 * 4096; + result = AV_CEIL_RSHIFT(h, 4) * AV_CEIL_RSHIFT(w, 4) + * (int64_t)entry->packet_scale.num / entry->packet_scale.den; + if (alpha && (entry->flags & DNXHD_444)) + result = (result * 3) >> 1; + result = (result + 2048) & -4096; return FFMAX(result, 8192); } diff --git a/libavcodec/dnxhddata.h b/libavcodec/dnxhddata.h index 898079cffc..21738af453 100644 --- a/libavcodec/dnxhddata.h +++ b/libavcodec/dnxhddata.h @@ -35,6 +35,7 @@ /** Frame headers, extra 0x00 added to end for parser */ #define DNXHD_HEADER_INITIAL 0x000002800100 #define DNXHD_HEADER_444 0x000002800200 +#define DNXHD_HEADER_RGBA 0x000002800400 /** Indicate that a CIDEntry value must be read in the bitstream */ #define DNXHD_VARIABLE 0 @@ -76,6 +77,7 @@ 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_RGBA || ff_dnxhd_check_header_prefix_hr(prefix)) return prefix; return 0; @@ -88,8 +90,8 @@ static av_always_inline uint64_t ff_dnxhd_parse_header_prefix(const uint8_t *buf return ff_dnxhd_check_header_prefix(prefix); } -int avpriv_dnxhd_get_frame_size(int cid); -int avpriv_dnxhd_get_hr_frame_size(int cid, int w, int h); +int avpriv_dnxhd_get_frame_size(int cid, int alpha); +int avpriv_dnxhd_get_hr_frame_size(int cid, int w, int h, int alpha); int avpriv_dnxhd_get_interlaced(int cid); #endif /* AVCODEC_DNXHDDATA_H */ diff --git a/libavcodec/dnxhdenc.c b/libavcodec/dnxhdenc.c index 2461c51727..fb059060aa 100644 --- a/libavcodec/dnxhdenc.c +++ b/libavcodec/dnxhdenc.c @@ -467,7 +467,7 @@ static av_cold int dnxhd_encode_init(AVCodecContext *avctx) if (ctx->cid_table->frame_size == DNXHD_VARIABLE) { ctx->frame_size = avpriv_dnxhd_get_hr_frame_size(ctx->cid, - avctx->width, avctx->height); + avctx->width, avctx->height, 0); av_assert0(ctx->frame_size >= 0); ctx->coding_unit_size = ctx->frame_size; } else { diff --git a/libavformat/mxfenc.c b/libavformat/mxfenc.c index 0c464d4cfd..653060ae75 100644 --- a/libavformat/mxfenc.c +++ b/libavformat/mxfenc.c @@ -2025,7 +2025,7 @@ static int mxf_parse_dnxhd_frame(AVFormatContext *s, AVStream *st, AVPacket *pkt { MXFContext *mxf = s->priv_data; MXFStreamContext *sc = st->priv_data; - int i, cid, frame_size = 0; + int i, alpha, cid, frame_size = 0; if (mxf->header_written) return 1; @@ -2034,6 +2034,7 @@ static int mxf_parse_dnxhd_frame(AVFormatContext *s, AVStream *st, AVPacket *pkt return 0; sc->codec_ul = NULL; + alpha = pkt->data[0x7] & 1; cid = AV_RB32(pkt->data + 0x28); for (i = 0; i < FF_ARRAY_ELEMS(mxf_dnxhd_codec_uls); i++) { if (cid == mxf_dnxhd_codec_uls[i].cid) { @@ -2053,8 +2054,8 @@ static int mxf_parse_dnxhd_frame(AVFormatContext *s, AVStream *st, AVPacket *pkt if (!sc->component_depth) return 0; - if ((frame_size = avpriv_dnxhd_get_frame_size(cid)) == DNXHD_VARIABLE) { - frame_size = avpriv_dnxhd_get_hr_frame_size(cid, st->codecpar->width, st->codecpar->height); + if ((frame_size = avpriv_dnxhd_get_frame_size(cid, alpha)) == DNXHD_VARIABLE) { + frame_size = avpriv_dnxhd_get_hr_frame_size(cid, st->codecpar->width, st->codecpar->height, alpha); } if (frame_size < 0) return 0; -- 2.29.2 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".