Unified · Split
| @@ -106,6 +106,91 @@ FF_ENABLE_DEPRECATION_WARNINGS · 105 unmodified lines | ||
| 106 | 106 | uavs3d_img_cpy_cvt(&frm_out, dec_frame, dec_frame->bit_depth); |
| 107 | 107 | } |
| 108 | 108 | |
| 109 | +#define UAVS3D_CHECK_INVALID_RANGE(v, l, r) ((v)<(l)||(v)>(r)) | |
| 110 | + | |
| 111 | +static int libuavs3d_on_seq_header(AVCodecContext *avctx) | |
| 112 | +{ | |
| 113 | + uavs3d_context *h = avctx->priv_data; | |
| 114 | + uavs3d_io_frm_t *frm_dec = &h->dec_frame; | |
| 115 | + struct uavs3d_com_seqh_t *seqh = frm_dec->seqhdr; | |
| 116 | + int ret; | |
| 117 | + | |
| 118 | + if (UAVS3D_CHECK_INVALID_RANGE(seqh->frame_rate_code, 0, 15)) { | |
| 119 | + av_log(avctx, AV_LOG_ERROR, "Invalid frame rate code: %d.\n", seqh->frame_rate_code); | |
| 120 | + seqh->frame_rate_code = 3; // default 25 fps | |
| 121 | + } else { | |
| 122 | + avctx->framerate.num = ff_avs3_frame_rate_tab[seqh->frame_rate_code].num; | |
| 123 | + avctx->framerate.den = ff_avs3_frame_rate_tab[seqh->frame_rate_code].den; | |
| 124 | + } | |
| 125 | + avctx->has_b_frames = seqh->output_reorder_delay; | |
| 126 | + avctx->pix_fmt = seqh->bit_depth_internal == 8 ? AV_PIX_FMT_YUV420P : AV_PIX_FMT_YUV420P10LE; | |
| 127 | + ret = ff_set_dimensions(avctx, seqh->horizontal_size, seqh->vertical_size); | |
| 128 | + if (ret < 0) | |
| 129 | + return ret; | |
| 130 | + h->got_seqhdr = 1; | |
| 131 | + | |
| 132 | + if (seqh->colour_description) { | |
| 133 | + if (UAVS3D_CHECK_INVALID_RANGE(seqh->colour_primaries, 0, 9) || | |
| 134 | + UAVS3D_CHECK_INVALID_RANGE(seqh->transfer_characteristics, 0, 14) || | |
| 135 | + UAVS3D_CHECK_INVALID_RANGE(seqh->matrix_coefficients, 0, 11)) { | |
| 136 | + av_log(avctx, AV_LOG_ERROR, | |
| 137 | + "Invalid colour description: primaries: %d" | |
| 138 | + "transfer characteristics: %d" | |
| 139 | + "matrix coefficients: %d.\n", | |
| 140 | + seqh->colour_primaries, | |
| 141 | + seqh->transfer_characteristics, | |
| 142 | + seqh->matrix_coefficients); | |
| 143 | + } else { | |
| 144 | + avctx->color_primaries = ff_avs3_color_primaries_tab[seqh->colour_primaries]; | |
| 145 | + avctx->color_trc = ff_avs3_color_transfer_tab [seqh->transfer_characteristics]; | |
| 146 | + avctx->colorspace = ff_avs3_color_matrix_tab [seqh->matrix_coefficients]; | |
| 147 | + } | |
| 148 | + } | |
| 149 | + | |
| 150 | + return 0; | |
| 151 | +} | |
| 152 | + | |
| 153 | +static int libuavs3d_decode_extradata(AVCodecContext *avctx) | |
| 154 | +{ | |
| 155 | + uavs3d_context *h = avctx->priv_data; | |
| 156 | + uint8_t *header = avctx->extradata; | |
| 157 | + int header_size = avctx->extradata_size; | |
| 158 | + uavs3d_io_frm_t *frm_dec = &h->dec_frame; | |
| 159 | + | |
| 160 | + if (avctx->extradata_size < 4) { | |
| 161 | + av_log(avctx, AV_LOG_WARNING, "Invalid extradata size %d\n", | |
| 162 | + avctx->extradata_size); | |
| 163 | + return 0; | |
| 164 | + } | |
| 165 | + | |
| 166 | + if (header[0] == 1) { | |
| 167 | + // Skip configurationVersion and sequence_header_length | |
| 168 | + header += 3; | |
| 169 | + // Also remove library_dependency_idc at the end | |
| 170 | + header_size -= 4; | |
| 171 | + } | |
| 172 | + | |
| 173 | + frm_dec->nal_type = 0; | |
| 174 | + frm_dec->pkt_pos = 0; | |
| 175 | + frm_dec->pkt_size = header_size; | |
| 176 | + frm_dec->bs = header; | |
| 177 | + frm_dec->bs_len = header_size; | |
| 178 | + frm_dec->pts = 0; | |
| 179 | + frm_dec->dts = 0; | |
| 180 | + uavs3d_decode(h->dec_handle, frm_dec); | |
| 181 | + if (frm_dec->nal_type == NAL_SEQ_HEADER) { | |
| 182 | + int ret = libuavs3d_on_seq_header(avctx); | |
| 183 | + if (ret < 0) | |
| 184 | + av_log(avctx, AV_LOG_WARNING, | |
| 185 | + "Process sequence header failed, %s\n", av_err2str(ret)); | |
| 186 | + } else { | |
| 187 | + av_log(avctx, AV_LOG_WARNING, | |
| 188 | + "Missing sequence header in extradata\n"); | |
| 189 | + } | |
| 190 | + | |
| 191 | + return 0; | |
| 192 | +} | |
| 193 | + | |
| 109 | 194 | static av_cold int libuavs3d_init(AVCodecContext *avctx) |
| 110 | 195 | { |
| 111 | 196 | uavs3d_context *h = avctx->priv_data; |
| @@ -120,6 +205,9 @@ static av_cold int libuavs3d_init(AVCodecContext *avctx) · 8 unmodified lines | ||
| 120 | 205 | return AVERROR(ENOMEM); |
| 121 | 206 | } |
| 122 | 207 | |
| 208 | + if (avctx->extradata) | |
| 209 | + return libuavs3d_decode_extradata(avctx); | |
| 210 | + | |
| 123 | 211 | return 0; |
| 124 | 212 | } |
| 125 | 213 | |
| @@ -146,7 +234,6 @@ static void libuavs3d_flush(AVCodecContext * avctx) · 20 unmodified lines | ||
| 146 | 234 | } |
| 147 | 235 | } |
| 148 | 236 | |
| 149 | −#define UAVS3D_CHECK_INVALID_RANGE(v, l, r) ((v)<(l)||(v)>(r)) | |
| 150 | 237 | static int libuavs3d_decode_frame(AVCodecContext *avctx, AVFrame *frm, |
| 151 | 238 | int *got_frame, AVPacket *avpkt) |
| 152 | 239 | { |
| @@ -207,38 +294,9 @@ FF_ENABLE_DEPRECATION_WARNINGS · 54 unmodified lines | ||
| 207 | 294 | buf_ptr += bs_len; |
| 208 | 295 | |
| 209 | 296 | if (frm_dec->nal_type == NAL_SEQ_HEADER) { |
| 210 | − struct uavs3d_com_seqh_t *seqh = frm_dec->seqhdr; | |
| 211 | − if (UAVS3D_CHECK_INVALID_RANGE(seqh->frame_rate_code, 0, 15)) { | |
| 212 | − av_log(avctx, AV_LOG_ERROR, "Invalid frame rate code: %d.\n", seqh->frame_rate_code); | |
| 213 | − seqh->frame_rate_code = 3; // default 25 fps | |
| 214 | − } else { | |
| 215 | − avctx->framerate.num = ff_avs3_frame_rate_tab[seqh->frame_rate_code].num; | |
| 216 | − avctx->framerate.den = ff_avs3_frame_rate_tab[seqh->frame_rate_code].den; | |
| 217 | − } | |
| 218 | − avctx->has_b_frames = seqh->output_reorder_delay; | |
| 219 | − avctx->pix_fmt = seqh->bit_depth_internal == 8 ? AV_PIX_FMT_YUV420P : AV_PIX_FMT_YUV420P10LE; | |
| 220 | − ret = ff_set_dimensions(avctx, seqh->horizontal_size, seqh->vertical_size); | |
| 297 | + ret = libuavs3d_on_seq_header(avctx); | |
| 221 | 298 | if (ret < 0) |
| 222 | 299 | return ret; |
| 223 | − h->got_seqhdr = 1; | |
| 224 | − | |
| 225 | − if (seqh->colour_description) { | |
| 226 | − if (UAVS3D_CHECK_INVALID_RANGE(seqh->colour_primaries, 0, 9) || | |
| 227 | − UAVS3D_CHECK_INVALID_RANGE(seqh->transfer_characteristics, 0, 14) || | |
| 228 | − UAVS3D_CHECK_INVALID_RANGE(seqh->matrix_coefficients, 0, 11)) { | |
| 229 | − av_log(avctx, AV_LOG_ERROR, | |
| 230 | − "Invalid colour description: primaries: %d" | |
| 231 | − "transfer characteristics: %d" | |
| 232 | − "matrix coefficients: %d.\n", | |
| 233 | − seqh->colour_primaries, | |
| 234 | − seqh->transfer_characteristics, | |
| 235 | − seqh->matrix_coefficients); | |
| 236 | − } else { | |
| 237 | − avctx->color_primaries = ff_avs3_color_primaries_tab[seqh->colour_primaries]; | |
| 238 | − avctx->color_trc = ff_avs3_color_transfer_tab [seqh->transfer_characteristics]; | |
| 239 | − avctx->colorspace = ff_avs3_color_matrix_tab [seqh->matrix_coefficients]; | |
| 240 | − } | |
| 241 | − } | |
| 242 | 300 | } |
| 243 | 301 | if (frm_dec->got_pic) { |
| 244 | 302 | break; |