| 112 | } |
| 113 | |
| 114 | static int apply_param_change(AVCodecContext *avctx, const AVPacket *avpkt) |
| 115 | { |
| 116 | int ret; |
| 117 | size_t size; |
| 118 | const uint8_t *data; |
| 119 | uint32_t flags; |
| 120 | int64_t val; |
| 121 | |
| 122 | data = av_packet_get_side_data(avpkt, AV_PKT_DATA_PARAM_CHANGE, &size); |
| 123 | if (!data) |
| 124 | return 0; |
| 125 | |
| 126 | if (!(avctx->codec->capabilities & AV_CODEC_CAP_PARAM_CHANGE)) { |
| 127 | av_log(avctx, AV_LOG_ERROR, "This decoder does not support parameter " |
| 128 | "changes, but PARAM_CHANGE side data was sent to it.\n"); |
| 129 | ret = AVERROR(EINVAL); |
| 130 | goto fail2; |
| 131 | } |
| 132 | |
| 133 | if (size < 4) |
| 134 | goto fail; |
| 135 | |
| 136 | flags = bytestream_get_le32(&data); |
| 137 | size -= 4; |
| 138 | |
| 139 | if (flags & AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE) { |
| 140 | if (size < 4) |
| 141 | goto fail; |
| 142 | val = bytestream_get_le32(&data); |
| 143 | if (val <= 0 || val > INT_MAX) { |
| 144 | av_log(avctx, AV_LOG_ERROR, "Invalid sample rate"); |
| 145 | ret = AVERROR_INVALIDDATA; |
| 146 | goto fail2; |
| 147 | } |
| 148 | avctx->sample_rate = val; |
| 149 | size -= 4; |
| 150 | } |
| 151 | if (flags & AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS) { |
| 152 | if (size < 8) |
| 153 | goto fail; |
| 154 | avctx->width = bytestream_get_le32(&data); |
| 155 | avctx->height = bytestream_get_le32(&data); |
| 156 | size -= 8; |
| 157 | ret = ff_set_dimensions(avctx, avctx->width, avctx->height); |
| 158 | if (ret < 0) |
| 159 | goto fail2; |
| 160 | } |
| 161 | |
| 162 | return 0; |
| 163 | fail: |
| 164 | av_log(avctx, AV_LOG_ERROR, "PARAM_CHANGE side data too small.\n"); |
| 165 | ret = AVERROR_INVALIDDATA; |
| 166 | fail2: |
| 167 | if (ret < 0) { |
| 168 | av_log(avctx, AV_LOG_ERROR, "Error applying parameter changes.\n"); |
| 169 | if (avctx->err_recognition & AV_EF_EXPLODE) |
| 170 | return ret; |
| 171 | } |
no test coverage detected