History

cbs_av1: Support redundant frame headers

Mark Thompson committed 8 years ago

Commit f5894171 parent 6bdb7713 files · +91 −12Browse files

Unified · Split

3 files
  1. libavcodec/cbs_av1.c +12 −4
  2. libavcodec/cbs_av1.h +4 −1
  3. libavcodec/cbs_av1_syntax_template.c +75 −7
libavcodec/cbs_av1.c+12−4
@@ -996,7 +996,10 @@ static int cbs_av1_read_unit(CodedBitstreamContext *ctx, · 995 unmodified lines
996996 case AV1_OBU_REDUNDANT_FRAME_HEADER:
997997 {
998998 err = cbs_av1_read_frame_header_obu(ctx, &gbc,
999− &obu->obu.frame_header);
999+ &obu->obu.frame_header,
1000+ obu->header.obu_type ==
1001+ AV1_OBU_REDUNDANT_FRAME_HEADER,
1002+ unit->data_ref);
10001003 if (err < 0)
10011004 return err;
10021005 }
@@ -1016,7 +1019,8 @@ static int cbs_av1_read_unit(CodedBitstreamContext *ctx, · 13 unmodified lines
10161019 break;
10171020 case AV1_OBU_FRAME:
10181021 {
1019− err = cbs_av1_read_frame_obu(ctx, &gbc, &obu->obu.frame);
1022+ err = cbs_av1_read_frame_obu(ctx, &gbc, &obu->obu.frame,
1023+ unit->data_ref);
10201024 if (err < 0)
10211025 return err;
10221026
@@ -1124,7 +1128,10 @@ static int cbs_av1_write_obu(CodedBitstreamContext *ctx, · 101 unmodified lines
11241128 case AV1_OBU_REDUNDANT_FRAME_HEADER:
11251129 {
11261130 err = cbs_av1_write_frame_header_obu(ctx, pbc,
1127− &obu->obu.frame_header);
1131+ &obu->obu.frame_header,
1132+ obu->header.obu_type ==
1133+ AV1_OBU_REDUNDANT_FRAME_HEADER,
1134+ NULL);
11281135 if (err < 0)
11291136 return err;
11301137 }
@@ -1141,7 +1148,7 @@ static int cbs_av1_write_obu(CodedBitstreamContext *ctx, · 10 unmodified lines
11411148 break;
11421149 case AV1_OBU_FRAME:
11431150 {
1144− err = cbs_av1_write_frame_obu(ctx, pbc, &obu->obu.frame);
1151+ err = cbs_av1_write_frame_obu(ctx, pbc, &obu->obu.frame, NULL);
11451152 if (err < 0)
11461153 return err;
11471154
@@ -1302,6 +1309,7 @@ static void cbs_av1_close(CodedBitstreamContext *ctx) · 154 unmodified lines
13021309 CodedBitstreamAV1Context *priv = ctx->priv_data;
13031310
13041311 av_buffer_unref(&priv->sequence_header_ref);
1312+ av_buffer_unref(&priv->frame_header_ref);
13051313
13061314 av_freep(&priv->write_buffer);
13071315 }
libavcodec/cbs_av1.h+4−1
@@ -399,7 +399,10 @@ typedef struct CodedBitstreamAV1Context { · 398 unmodified lines
399399 AV1RawSequenceHeader *sequence_header;
400400 AVBufferRef *sequence_header_ref;
401401
402− int seen_frame_header;
402+ int seen_frame_header;
403+ AVBufferRef *frame_header_ref;
404+ uint8_t *frame_header;
405+ size_t frame_header_size;
403406
404407 int temporal_id;
405408 int spatial_id;
libavcodec/cbs_av1_syntax_template.c+75−7
@@ -1463,24 +1463,90 @@ static int FUNC(uncompressed_header)(CodedBitstreamContext *ctx, RWContext *rw, · 1462 unmodified lines
14631463 }
14641464
14651465 static int FUNC(frame_header_obu)(CodedBitstreamContext *ctx, RWContext *rw,
1466− AV1RawFrameHeader *current)
1466+ AV1RawFrameHeader *current, int redundant,
1467+ AVBufferRef *rw_buffer_ref)
14671468 {
14681469 CodedBitstreamAV1Context *priv = ctx->priv_data;
1469− int err;
1470−
1471− HEADER("Frame Header");
1470+ int start_pos, fh_bits, fh_bytes, err;
1471+ uint8_t *fh_start;
14721472
14731473 if (priv->seen_frame_header) {
1474− // Nothing to do.
1474+ if (!redundant) {
1475+ av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid repeated "
1476+ "frame header OBU.\n");
1477+ return AVERROR_INVALIDDATA;
1478+ } else {
1479+ GetBitContext fh;
1480+ size_t i, b;
1481+ uint32_t val;
1482+
1483+ HEADER("Redundant Frame Header");
1484+
1485+ av_assert0(priv->frame_header_ref && priv->frame_header);
1486+
1487+ init_get_bits(&fh, priv->frame_header,
1488+ priv->frame_header_size);
1489+ for (i = 0; i < priv->frame_header_size; i += 8) {
1490+ b = FFMIN(priv->frame_header_size - i, 8);
1491+ val = get_bits(&fh, b);
1492+ xf(b, frame_header_copy[i],
1493+ val, val, val, 1, i / 8);
1494+ }
1495+ }
14751496 } else {
1497+ if (redundant)
1498+ HEADER("Redundant Frame Header (used as Frame Header)");
1499+ else
1500+ HEADER("Frame Header");
1501+
14761502 priv->seen_frame_header = 1;
14771503
1504+#ifdef READ
1505+ start_pos = get_bits_count(rw);
1506+#else
1507+ start_pos = put_bits_count(rw);
1508+#endif
1509+
14781510 CHECK(FUNC(uncompressed_header)(ctx, rw, current));
14791511
14801512 if (current->show_existing_frame) {
14811513 priv->seen_frame_header = 0;
14821514 } else {
14831515 priv->seen_frame_header = 1;
1516+
1517+ av_buffer_unref(&priv->frame_header_ref);
1518+
1519+#ifdef READ
1520+ fh_bits = get_bits_count(rw) - start_pos;
1521+ fh_start = (uint8_t*)rw->buffer + start_pos / 8;
1522+#else
1523+ // Need to flush the bitwriter so that we can copy its output,
1524+ // but use a copy so we don't affect the caller's structure.
1525+ {
1526+ PutBitContext tmp = *rw;
1527+ flush_put_bits(&tmp);
1528+ }
1529+
1530+ fh_bits = put_bits_count(rw) - start_pos;
1531+ fh_start = rw->buf + start_pos / 8;
1532+#endif
1533+ fh_bytes = (fh_bits + 7) / 8;
1534+
1535+ priv->frame_header_size = fh_bits;
1536+
1537+ if (rw_buffer_ref) {
1538+ priv->frame_header_ref = av_buffer_ref(rw_buffer_ref);
1539+ if (!priv->frame_header_ref)
1540+ return AVERROR(ENOMEM);
1541+ priv->frame_header = fh_start;
1542+ } else {
1543+ priv->frame_header_ref =
1544+ av_buffer_alloc(fh_bytes + AV_INPUT_BUFFER_PADDING_SIZE);
1545+ if (!priv->frame_header_ref)
1546+ return AVERROR(ENOMEM);
1547+ priv->frame_header = priv->frame_header_ref->data;
1548+ memcpy(priv->frame_header, fh_start, fh_bytes);
1549+ }
14841550 }
14851551 }
14861552
@@ -1524,11 +1590,13 @@ static int FUNC(tile_group_obu)(CodedBitstreamContext *ctx, RWContext *rw, · 37 unmodified lines
15241590 }
15251591
15261592 static int FUNC(frame_obu)(CodedBitstreamContext *ctx, RWContext *rw,
1527− AV1RawFrame *current)
1593+ AV1RawFrame *current,
1594+ AVBufferRef *rw_buffer_ref)
15281595 {
15291596 int err;
15301597
1531− CHECK(FUNC(frame_header_obu)(ctx, rw, &current->header));
1598+ CHECK(FUNC(frame_header_obu)(ctx, rw, &current->header,
1599+ 0, rw_buffer_ref));
15321600
15331601 CHECK(FUNC(byte_alignment)(ctx, rw));
15341602

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t