[FFmpeg-devel] [PATCH v2 25/36] vaapi_encode_mjpeg: Use CBS to store parameters and write headers
Mark Thompson
sw at jkqxz.net
Sun Jun 17 17:11:48 EEST 2018
On 15/06/18 02:37, Xiang, Haihao wrote:
> On Fri, 2018-06-08 at 00:43 +0100, Mark Thompson wrote:
>> Also adds greyscale, 4:2:2, 4:4:4 and RGB support.
>> ---
>> configure | 2 +-
>> doc/encoders.texi | 17 +-
>> libavcodec/vaapi_encode_mjpeg.c | 529 +++++++++++++++++++++++++------------
>> ---
>> 3 files changed, 347 insertions(+), 201 deletions(-)
>>
>> ...
>> diff --git a/libavcodec/vaapi_encode_mjpeg.c b/libavcodec/vaapi_encode_mjpeg.c
>> index f76645425a..2f79070e58 100644
>> --- a/libavcodec/vaapi_encode_mjpeg.c
>> +++ b/libavcodec/vaapi_encode_mjpeg.c
>> ...
>> +static int vaapi_encode_mjpeg_write_image_header(AVCodecContext *avctx,
>> + VAAPIEncodePicture *pic,
>> + VAAPIEncodeSlice *slice,
>> + char *data, size_t
>> *data_len)
>> {
>> - int i, mt;
>> -
>> - ++src_lengths;
>> + VAAPIEncodeMJPEGContext *priv = avctx->priv_data;
>> + CodedBitstreamFragment *frag = &priv->current_fragment;
>> + int err;
>> +
>> + if (priv->jfif) {
>> + err = ff_cbs_insert_unit_content(priv->cbc, frag, -1,
>> + JPEG_MARKER_APPN + 0,
>> + &priv->jfif_header, NULL);
>> + if (err < 0)
>> + goto fail;
>> + }
>>
>> - mt = 0;
>> - for (i = 0; i < 16; i++)
>> - mt += (dst_lengths[i] = src_lengths[i]);
>> + err = ff_cbs_insert_unit_content(priv->cbc, frag, -1,
>> + JPEG_MARKER_DQT,
>> + &priv->quant_tables, NULL);
>> + if (err < 0)
>> + goto fail;
>> +
>> + err = ff_cbs_insert_unit_content(priv->cbc, frag, -1,
>> + JPEG_MARKER_SOF0,
>> + &priv->frame_header, NULL);
>> + if (err < 0)
>> + goto fail;
>> +
>> + if (priv->huffman) {
>> + err = ff_cbs_insert_unit_content(priv->cbc, frag, -1,
>> + JPEG_MARKER_DHT,
>> + &priv->huffman_tables, NULL);
>> + if (err < 0)
>> + goto fail;
>> + }
>>
>> - for (i = 0; i < mt; i++)
>> - dst_values[i] = src_values[i];
>> -}
>> + err = ff_cbs_insert_unit_content(priv->cbc, frag, -1,
>> + JPEG_MARKER_SOS,
>> + &priv->scan, NULL);
>> + if (err < 0)
>> + goto fail;
>>
>> -static av_cold void vaapi_encode_mjpeg_init_tables(AVCodecContext *avctx)
>> -{
>> - VAAPIEncodeMJPEGContext *priv = avctx->priv_data;
>> - VAQMatrixBufferJPEG *quant = &priv->quant_tables;
>> - VAHuffmanTableBufferJPEGBaseline *huff = &priv->huffman_tables;
>> - int i;
>> -
>> - quant->load_lum_quantiser_matrix = 1;
>> - quant->load_chroma_quantiser_matrix = 1;
>> + err = ff_cbs_write_fragment_data(priv->cbc, frag);
>> + if (err < 0) {
>> + av_log(avctx, AV_LOG_ERROR, "Failed to write image header.\n");
>> + return err;
>
> Should it be 'goto fail' ? Some new units have been inserted to the fragment so
> ff_cbs_fragment_uninit() should be called to release resources.
Yep, fixed.
>> + }
>>
>> - for (i = 0; i < 64; i++) {
>> - quant->lum_quantiser_matrix[i] =
>> - vaapi_encode_mjpeg_quant_luminance[i];
>> - quant->chroma_quantiser_matrix[i] =
>> - vaapi_encode_mjpeg_quant_chrominance[i];
>> + if (*data_len < 8 * frag->data_size) {
>> + av_log(avctx, AV_LOG_ERROR, "Image header too large: "
>> + "%zu < %zu.\n", *data_len, 8 * frag->data_size);
>> + err = AVERROR(ENOSPC);
>> + goto fail;
>
> Could you change the last parameter name of this function to bit_len or
> bit_data_len? I think it is more readable and user don't need to think why frag-
>> data_size is multiplied by 8.
I don't think I agree? It matches the naming and style used in all of the other codecs in these write-header functions - compare for example <http://git.videolan.org/?p=ffmpeg.git;a=blob;f=libavcodec/vaapi_encode_h264.c;h=905c50760e2ba88f809b1e1a2e6059fce7134d53;hb=HEAD#l115>.
>> }
>>
>> - huff->load_huffman_table[0] = 1;
>> - vaapi_encode_mjpeg_copy_huffman(huff->huffman_table[0].num_dc_codes,
>> - huff->huffman_table[0].dc_values,
>> - avpriv_mjpeg_bits_dc_luminance,
>> - avpriv_mjpeg_val_dc);
>> - vaapi_encode_mjpeg_copy_huffman(huff->huffman_table[0].num_ac_codes,
>> - huff->huffman_table[0].ac_values,
>> - avpriv_mjpeg_bits_ac_luminance,
>> - avpriv_mjpeg_val_ac_luminance);
>> - memset(huff->huffman_table[0].pad, 0, sizeof(huff-
>>> huffman_table[0].pad));
>> -
>> - huff->load_huffman_table[1] = 1;
>> - vaapi_encode_mjpeg_copy_huffman(huff->huffman_table[1].num_dc_codes,
>> - huff->huffman_table[1].dc_values,
>> - avpriv_mjpeg_bits_dc_chrominance,
>> - avpriv_mjpeg_val_dc);
>> - vaapi_encode_mjpeg_copy_huffman(huff->huffman_table[1].num_ac_codes,
>> - huff->huffman_table[1].ac_values,
>> - avpriv_mjpeg_bits_ac_chrominance,
>> - avpriv_mjpeg_val_ac_chrominance);
>> - memset(huff->huffman_table[1].pad, 0, sizeof(huff-
>>> huffman_table[1].pad));
>> -}
>> + // Remove the EOI at the end of the fragment.
>> + memcpy(data, frag->data, frag->data_size - 2);
>> + *data_len = 8 * (frag->data_size - 2);
>>
>> -static void vaapi_encode_mjpeg_write_marker(PutBitContext *pbc, int marker)
>> -{
>> - put_bits(pbc, 8, 0xff);
>> - put_bits(pbc, 8, marker);
>> + err = 0;
>> +fail:
>> + ff_cbs_fragment_uninit(priv->cbc, frag);
>> + return err;
>> }
>> ...
Thanks,
- Mark
More information about the ffmpeg-devel
mailing list