[FFmpeg-devel] [PATCH 23/26] lavc/cbs: Add JPEG support
Mark Thompson
sw at jkqxz.net
Fri Apr 27 01:23:04 EEST 2018
On 25/04/18 23:23, James Almer wrote:
> On 4/25/2018 6:31 PM, Mark Thompson wrote:
>> +static int cbs_jpeg_split_fragment(CodedBitstreamContext *ctx,
>> + CodedBitstreamFragment *frag,
>> + int header)
>> +{
>> + AVBufferRef *data_ref;
>> + uint8_t *data;
>> + size_t data_size;
>> + int unit, start, end, marker, next_start, next_marker;
>> + int err, i, j, length;
>> +
>> + if (frag->data_size < 4) {
>> + // Definitely too short to be meaningful.
>> + return AVERROR_INVALIDDATA;
>> + }
>> +
>> + for (i = 0; i + 1 < frag->data_size && frag->data[i] != 0xff; i++);
>> + if (i > 0) {
>> + av_log(ctx->log_ctx, AV_LOG_WARNING, "Discarding %d bytes at "
>> + "beginning of image.\n", i);
>> + }
>> + for (++i; i + 1 < frag->data_size && frag->data[i] == 0xff; i++);
>> + if (i + 1 >= frag->data_size && frag->data[i]) {
>> + av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid JPEG image: "
>> + "no SOI marker found.\n");
>> + return AVERROR_INVALIDDATA;
>> + }
>> + marker = frag->data[i];
>> + if (marker != JPEG_MARKER_SOI) {
>> + av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid JPEG image: first "
>> + "marker is %02x, should be SOI.\n", marker);
>> + return AVERROR_INVALIDDATA;
>> + }
>> + for (++i; i + 1 < frag->data_size && frag->data[i] == 0xff; i++);
>> + if (i + 1 >= frag->data_size) {
>> + av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid JPEG image: "
>> + "no image content found.\n");
>> + return AVERROR_INVALIDDATA;
>> + }
>> + marker = frag->data[i];
>> + start = i + 1;
>> +
>> + for (unit = 0;; unit++) {
>> + if (marker == JPEG_MARKER_EOI) {
>> + break;
>> + } else if (marker == JPEG_MARKER_SOS) {
>> + for (i = start; i + 1 < frag->data_size; i++) {
>> + if (frag->data[i] != 0xff)
>> + continue;
>> + end = i;
>> + for (++i; i + 1 < frag->data_size &&
>> + frag->data[i] == 0xff; i++);
>> + if (i + 1 >= frag->data_size) {
>> + next_marker = -1;
>> + } else {
>> + if (frag->data[i] == 0x00)
>> + continue;
>> + next_marker = frag->data[i];
>> + next_start = i + 1;
>> + }
>> + break;
>> + }
>> + } else {
>> + i = start;
>> + if (i + 2 > frag->data_size) {
>> + av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid JPEG image: "
>> + "truncated at %02x marker.\n", marker);
>> + return AVERROR_INVALIDDATA;
>> + }
>> + length = AV_RB16(frag->data + i);
>> + if (i + length > frag->data_size) {
>> + av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid JPEG image: "
>> + "truncated at %02x marker segment.\n", marker);
>> + return AVERROR_INVALIDDATA;
>> + }
>> + end = start + length;
>> +
>> + i = end;
>> + if (frag->data[i] != 0xff) {
>> + next_marker = -1;
>> + } else {
>> + for (++i; i + 1 < frag->data_size &&
>> + frag->data[i] == 0xff; i++);
>> + if (i + 1 >= frag->data_size) {
>> + next_marker = -1;
>> + } else {
>> + next_marker = frag->data[i];
>> + next_start = i + 1;
>> + }
>> + }
>> + }
>> +
>> + if (marker == JPEG_MARKER_SOS) {
>> + length = AV_RB16(frag->data + start);
>> +
>> + data_ref = av_buffer_alloc(end - start +
>> + AV_INPUT_BUFFER_PADDING_SIZE);
>
> Allocating an AVBufferRef here, letting ff_cbs_insert_unit_data()
> generate a new reference to it, then unreffing the first one seems
> wasteful/redundant.
>
> Use av_malloc(), set data_ref to NULL, and let ff_cbs_insert_unit_data()
> create the AVBufferRef by taking ownership of the malloc'd data array
> instead. You'd then only need to free said data array if
> ff_cbs_insert_unit_data() fails.
Right, yes. Changed locally.
Thanks,
- Mark
More information about the ffmpeg-devel
mailing list