- CodedBitstreamFragment *au = &ctx->access_unit;
- int err, i, j, has_sps;
- H264RawAUD aud;
-
- err = ff_bsf_get_packet_ref(bsf, pkt);
- if (err < 0)
- return err;
-
- err = ff_cbs_read_packet(ctx->cbc, au, pkt);
- if (err < 0) {
- av_log(bsf, AV_LOG_ERROR, "Failed to read packet.\n");
- goto fail;
- }
-
- if (au->nb_units == 0) {
- av_log(bsf, AV_LOG_ERROR, "No NAL units in packet.\n");
- err = AVERROR_INVALIDDATA;
- goto fail;
- }
-
- // If an AUD is present, it must be the first NAL unit.
- if (au->units[0].type == H264_NAL_AUD) {
- if (ctx->aud == REMOVE)
- ff_cbs_delete_unit(ctx->cbc, au, 0);
- } else {
- if (ctx->aud == INSERT) {
- static const int primary_pic_type_table[] = {
- 0x084, // 2, 7
- 0x0a5, // 0, 2, 5, 7
- 0x0e7, // 0, 1, 2, 5, 6, 7
- 0x210, // 4, 9
- 0x318, // 3, 4, 8, 9
- 0x294, // 2, 4, 7, 9
- 0x3bd, // 0, 2, 3, 4, 5, 7, 8, 9
- 0x3ff, // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
- };
- int primary_pic_type_mask = 0xff;
-
- for (i = 0; i < au->nb_units; i++) {
- if (au->units[i].type == H264_NAL_SLICE ||
- au->units[i].type == H264_NAL_IDR_SLICE) {
- H264RawSlice *slice = au->units[i].content;
- for (j = 0; j < FF_ARRAY_ELEMS(primary_pic_type_table); j++) {
- if (!(primary_pic_type_table[j] &
- (1 << slice->header.slice_type)))
- primary_pic_type_mask &= ~(1 << j);
- }
- }
- }
- for (j = 0; j < FF_ARRAY_ELEMS(primary_pic_type_table); j++)
- if (primary_pic_type_mask & (1 << j))
- break;
- if (j >= FF_ARRAY_ELEMS(primary_pic_type_table)) {
- av_log(bsf, AV_LOG_ERROR, "No usable primary_pic_type: "
- "invalid slice types?\n");
- err = AVERROR_INVALIDDATA;
- goto fail;
- }
-
- aud = (H264RawAUD) {
- .nal_unit_header.nal_unit_type = H264_NAL_AUD,
- .primary_pic_type = j,
- };
-
- err = ff_cbs_insert_unit_content(ctx->cbc, au,
- 0, H264_NAL_AUD, &aud, NULL);
- if (err < 0) {
- av_log(bsf, AV_LOG_ERROR, "Failed to insert AUD.\n");
- goto fail;
- }
- }
- }
-
- has_sps = 0;
- for (i = 0; i < au->nb_units; i++) {
- if (au->units[i].type == H264_NAL_SPS) {
- err = h264_metadata_update_sps(bsf, au->units[i].content);
- if (err < 0)
- goto fail;
- has_sps = 1;
+ SEIRawMessage *message;
+ int err;
+
+ message = NULL;
+ while (ff_cbs_sei_find_message(ctx->common.output, au,
+ SEI_TYPE_DISPLAY_ORIENTATION,
+ &message) == 0) {
+ H264RawSEIDisplayOrientation *disp = message->payload;
+ int32_t *matrix;
+
+ matrix = av_malloc(9 * sizeof(int32_t));
+ if (!matrix)
+ return AVERROR(ENOMEM);
+
+ av_display_rotation_set(matrix,
+ disp->anticlockwise_rotation *
+ 180.0 / 65536.0);
+ av_display_matrix_flip(matrix, disp->hor_flip, disp->ver_flip);
+
+ // If there are multiple display orientation messages in an
+ // access unit, then the last one added to the packet (i.e.
+ // the first one in the access unit) will prevail.
+ err = av_packet_add_side_data(pkt, AV_PKT_DATA_DISPLAYMATRIX,
+ (uint8_t*)matrix,
+ 9 * sizeof(int32_t));
+ if (err < 0) {
+ av_log(bsf, AV_LOG_ERROR, "Failed to attach extracted "
+ "displaymatrix side data to packet.\n");
+ av_free(matrix);
+ return AVERROR(ENOMEM);