You've already forked FFmpeg
mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-07-11 14:30:22 +02:00
avcodec/dnxhd_parser: take into account compressed frame size and skip it
Fixes #6214 and vsynth1-dnxhd-720p-hr-lb. Signed-off-by: Paul B Mahol <onemda@gmail.com>
This commit is contained in:
@ -31,8 +31,24 @@ typedef struct {
|
|||||||
ParseContext pc;
|
ParseContext pc;
|
||||||
int interlaced;
|
int interlaced;
|
||||||
int cur_field; /* first field is 0, second is 1 */
|
int cur_field; /* first field is 0, second is 1 */
|
||||||
|
int cur_byte;
|
||||||
|
int remaining;
|
||||||
|
int w, h;
|
||||||
} DNXHDParserContext;
|
} DNXHDParserContext;
|
||||||
|
|
||||||
|
static int dnxhd_get_hr_frame_size(int cid, int w, int h)
|
||||||
|
{
|
||||||
|
int result, i = ff_dnxhd_get_cid_table(cid);
|
||||||
|
|
||||||
|
if (i < 0)
|
||||||
|
return i;
|
||||||
|
|
||||||
|
result = ((h + 15) / 16) * ((w + 15) / 16) * ff_dnxhd_cid_table[i].packet_scale.num / ff_dnxhd_cid_table[i].packet_scale.den;
|
||||||
|
result = (result + 2048) / 4096 * 4096;
|
||||||
|
|
||||||
|
return FFMAX(result, 8192);
|
||||||
|
}
|
||||||
|
|
||||||
static int dnxhd_find_frame_end(DNXHDParserContext *dctx,
|
static int dnxhd_find_frame_end(DNXHDParserContext *dctx,
|
||||||
const uint8_t *buf, int buf_size)
|
const uint8_t *buf, int buf_size)
|
||||||
{
|
{
|
||||||
@ -51,30 +67,65 @@ static int dnxhd_find_frame_end(DNXHDParserContext *dctx,
|
|||||||
pic_found = 1;
|
pic_found = 1;
|
||||||
interlaced = (state&2)>>1; /* byte following the 5-byte header prefix */
|
interlaced = (state&2)>>1; /* byte following the 5-byte header prefix */
|
||||||
cur_field = state&1;
|
cur_field = state&1;
|
||||||
|
dctx->cur_byte = 0;
|
||||||
|
dctx->remaining = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pic_found) {
|
if (pic_found && !dctx->remaining) {
|
||||||
if (!buf_size) /* EOF considered as end of frame */
|
if (!buf_size) /* EOF considered as end of frame */
|
||||||
return 0;
|
return 0;
|
||||||
for (; i < buf_size; i++) {
|
for (; i < buf_size; i++) {
|
||||||
|
dctx->cur_byte++;
|
||||||
state = (state << 8) | buf[i];
|
state = (state << 8) | buf[i];
|
||||||
if (ff_dnxhd_check_header_prefix(state & 0xffffffffff00LL) != 0) {
|
|
||||||
if (!interlaced || dctx->cur_field) {
|
if (dctx->cur_byte == 24) {
|
||||||
|
dctx->h = (state >> 32) & 0xFFFF;
|
||||||
|
} else if (dctx->cur_byte == 26) {
|
||||||
|
dctx->w = (state >> 32) & 0xFFFF;
|
||||||
|
} else if (dctx->cur_byte == 42) {
|
||||||
|
int cid = (state >> 32) & 0xFFFFFFFF;
|
||||||
|
|
||||||
|
if (cid <= 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
dctx->remaining = avpriv_dnxhd_get_frame_size(cid);
|
||||||
|
if (dctx->remaining <= 0) {
|
||||||
|
dctx->remaining = dnxhd_get_hr_frame_size(cid, dctx->w, dctx->h);
|
||||||
|
if (dctx->remaining <= 0)
|
||||||
|
return dctx->remaining;
|
||||||
|
}
|
||||||
|
if (buf_size - i >= dctx->remaining && (!dctx->interlaced || dctx->cur_field)) {
|
||||||
|
int remaining = dctx->remaining;
|
||||||
|
|
||||||
pc->frame_start_found = 0;
|
pc->frame_start_found = 0;
|
||||||
pc->state64 = -1;
|
pc->state64 = -1;
|
||||||
dctx->interlaced = interlaced;
|
dctx->interlaced = interlaced;
|
||||||
dctx->cur_field = 0;
|
dctx->cur_field = 0;
|
||||||
return i - 5;
|
dctx->cur_byte = 0;
|
||||||
|
dctx->remaining = 0;
|
||||||
|
return remaining;
|
||||||
} else {
|
} else {
|
||||||
/* continue, to get the second field */
|
dctx->remaining -= buf_size;
|
||||||
dctx->interlaced = interlaced = (state&2)>>1;
|
|
||||||
dctx->cur_field = cur_field = state&1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (pic_found) {
|
||||||
|
if (dctx->remaining > buf_size) {
|
||||||
|
dctx->remaining -= buf_size;
|
||||||
|
} else {
|
||||||
|
int remaining = dctx->remaining;
|
||||||
|
|
||||||
|
pc->frame_start_found = 0;
|
||||||
|
pc->state64 = -1;
|
||||||
|
dctx->interlaced = interlaced;
|
||||||
|
dctx->cur_field = 0;
|
||||||
|
dctx->cur_byte = 0;
|
||||||
|
dctx->remaining = 0;
|
||||||
|
return remaining;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pc->frame_start_found = pic_found;
|
pc->frame_start_found = pic_found;
|
||||||
pc->state64 = state;
|
pc->state64 = state;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
08cbfe9b9f671cdb9dddc9307121d107 *tests/data/fate/vsynth1-dnxhd-720p-hr-lb.dnxhd
|
08cbfe9b9f671cdb9dddc9307121d107 *tests/data/fate/vsynth1-dnxhd-720p-hr-lb.dnxhd
|
||||||
409600 tests/data/fate/vsynth1-dnxhd-720p-hr-lb.dnxhd
|
409600 tests/data/fate/vsynth1-dnxhd-720p-hr-lb.dnxhd
|
||||||
22eb87f0f8a50278355006fef70073a9 *tests/data/fate/vsynth1-dnxhd-720p-hr-lb.out.rawvideo
|
77e510e3538313b1cbafb86ed248d2df *tests/data/fate/vsynth1-dnxhd-720p-hr-lb.out.rawvideo
|
||||||
stddev: 7.49 PSNR: 30.63 MAXDIFF: 64 bytes: 7603200/ 608256
|
stddev: 7.50 PSNR: 30.62 MAXDIFF: 64 bytes: 7603200/ 760320
|
||||||
|
Reference in New Issue
Block a user