static av_cold int amrnb_decode_init(AVCodecContext *avctx) { AMRContext *p = avctx->priv_data; int i; if (avctx->channels > 1) { avpriv_report_missing_feature(avctx, "multi-channel AMR"); return AVERROR_PATCHWELCOME; } avctx->channels = 1; avctx->channel_layout = AV_CH_LAYOUT_MONO; if (!avctx->sample_rate) avctx->sample_rate = 8000; avctx->sample_fmt = AV_SAMPLE_FMT_FLT; // p->excitation always points to the same position in p->excitation_buf p->excitation = &p->excitation_buf[PITCH_DELAY_MAX + LP_FILTER_ORDER + 1]; for (i = 0; i < LP_FILTER_ORDER; i++) { p->prev_lsp_sub4[i] = lsp_sub4_init[i] * 1000 / (float)(1 << 15); p->lsf_avg[i] = p->lsf_q[3][i] = lsp_avg_init[i] / (float)(1 << 15); } for (i = 0; i < 4; i++) p->prediction_error[i] = MIN_ENERGY; ff_acelp_filter_init(&p->acelpf_ctx); ff_acelp_vectors_init(&p->acelpv_ctx); ff_celp_filter_init(&p->celpf_ctx); ff_celp_math_init(&p->celpm_ctx); return 0; }
static av_cold int amrwb_decode_init(AVCodecContext *avctx) { AMRWBContext *ctx = avctx->priv_data; int i; if (avctx->channels > 1) { avpriv_report_missing_feature(avctx, "multi-channel AMR"); return AVERROR_PATCHWELCOME; } avctx->channels = 1; avctx->channel_layout = AV_CH_LAYOUT_MONO; if (!avctx->sample_rate) avctx->sample_rate = 16000; avctx->sample_fmt = AV_SAMPLE_FMT_FLT; av_lfg_init(&ctx->prng, 1); ctx->excitation = &ctx->excitation_buf[AMRWB_P_DELAY_MAX + LP_ORDER + 1]; ctx->first_frame = 1; for (i = 0; i < LP_ORDER; i++) ctx->isf_past_final[i] = isf_init[i] * (1.0f / (1 << 15)); for (i = 0; i < 4; i++) ctx->prediction_error[i] = MIN_ENERGY; ff_acelp_filter_init(&ctx->acelpf_ctx); ff_acelp_vectors_init(&ctx->acelpv_ctx); ff_celp_filter_init(&ctx->celpf_ctx); ff_celp_math_init(&ctx->celpm_ctx); return 0; }
int ff_rv10_encode_picture_header(MpegEncContext *s, int picture_number) { int full_frame= 0; avpriv_align_put_bits(&s->pb); put_bits(&s->pb, 1, 1); /* marker */ put_bits(&s->pb, 1, (s->pict_type == AV_PICTURE_TYPE_P)); put_bits(&s->pb, 1, 0); /* not PB frame */ put_bits(&s->pb, 5, s->qscale); if (s->pict_type == AV_PICTURE_TYPE_I) { /* specific MPEG like DC coding not used */ } /* if multiple packets per frame are sent, the position at which to display the macroblocks is coded here */ if(!full_frame){ if (s->mb_width * s->mb_height >= (1U << 12)) { avpriv_report_missing_feature(s->avctx, "Encoding frames with %d (>= 4096) macroblocks", s->mb_width * s->mb_height); return AVERROR(ENOSYS); } put_bits(&s->pb, 6, 0); /* mb_x */ put_bits(&s->pb, 6, 0); /* mb_y */ put_bits(&s->pb, 12, s->mb_width * s->mb_height); } put_bits(&s->pb, 3, 0); /* ignored */ return 0; }
static int atrac3p_decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, AVPacket *avpkt) { ATRAC3PContext *ctx = avctx->priv_data; AVFrame *frame = data; int i, ret, ch_unit_id, ch_block = 0, out_ch_index = 0, channels_to_process; float **samples_p = (float **)frame->extended_data; frame->nb_samples = ATRAC3P_FRAME_SAMPLES; if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) return ret; if ((ret = init_get_bits8(&ctx->gb, avpkt->data, avpkt->size)) < 0) return ret; if (get_bits1(&ctx->gb)) { av_log(avctx, AV_LOG_ERROR, "Invalid start bit!\n"); return AVERROR_INVALIDDATA; } while (get_bits_left(&ctx->gb) >= 2 && (ch_unit_id = get_bits(&ctx->gb, 2)) != CH_UNIT_TERMINATOR) { if (ch_unit_id == CH_UNIT_EXTENSION) { avpriv_report_missing_feature(avctx, "Channel unit extension"); return AVERROR_PATCHWELCOME; } if (ch_block >= ctx->num_channel_blocks || ctx->channel_blocks[ch_block] != ch_unit_id) { av_log(avctx, AV_LOG_ERROR, "Frame data doesn't match channel configuration!\n"); return AVERROR_INVALIDDATA; } ctx->ch_units[ch_block].unit_type = ch_unit_id; channels_to_process = ch_unit_id + 1; if ((ret = ff_atrac3p_decode_channel_unit(&ctx->gb, &ctx->ch_units[ch_block], channels_to_process, avctx)) < 0) return ret; decode_residual_spectrum(&ctx->ch_units[ch_block], ctx->samples, channels_to_process, avctx); reconstruct_frame(ctx, &ctx->ch_units[ch_block], channels_to_process, avctx); for (i = 0; i < channels_to_process; i++) memcpy(samples_p[out_ch_index + i], ctx->outp_buf[i], ATRAC3P_FRAME_SAMPLES * sizeof(**samples_p)); ch_block++; out_ch_index += channels_to_process; } *got_frame_ptr = 1; return FFMIN(avctx->block_align, avpkt->size); }
static av_cold int rscc_init(AVCodecContext *avctx) { RsccContext *ctx = avctx->priv_data; /* These needs to be set to estimate uncompressed buffer */ int ret = av_image_check_size(avctx->width, avctx->height, 0, avctx); if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "Invalid image size %dx%d.\n", avctx->width, avctx->height); return ret; } /* Allocate reference frame */ ctx->reference = av_frame_alloc(); if (!ctx->reference) return AVERROR(ENOMEM); /* Get pixel format and the size of the pixel */ if (avctx->codec_tag == MKTAG('I', 'S', 'C', 'C')) { avctx->pix_fmt = AV_PIX_FMT_BGRA; ctx->component_size = 4; } else if (avctx->codec_tag == MKTAG('R', 'S', 'C', 'C')) { ctx->component_size = avctx->bits_per_coded_sample / 8; switch (avctx->bits_per_coded_sample) { case 8: avpriv_report_missing_feature(avctx, "8 bits per pixel"); return AVERROR_PATCHWELCOME; case 16: avctx->pix_fmt = AV_PIX_FMT_RGB555LE; break; case 24: avctx->pix_fmt = AV_PIX_FMT_BGR24; break; case 32: avctx->pix_fmt = AV_PIX_FMT_BGR0; break; default: av_log(avctx, AV_LOG_ERROR, "Invalid bits per pixel value (%d)\n", avctx->bits_per_coded_sample); return AVERROR_INVALIDDATA; } } else { avctx->pix_fmt = AV_PIX_FMT_BGR0; ctx->component_size = 4; av_log(avctx, AV_LOG_WARNING, "Invalid codec tag\n"); } /* Store the value to check for keyframes */ ctx->inflated_size = avctx->width * avctx->height * ctx->component_size; /* Allocate maximum size possible, a full frame */ ctx->inflated_buf = av_malloc(ctx->inflated_size); if (!ctx->inflated_buf) return AVERROR(ENOMEM); return 0; }
static int v4l2_check_b_frame_support(V4L2m2mContext *s) { if (s->avctx->max_b_frames) av_log(s->avctx, AV_LOG_WARNING, "Encoder does not support b-frames yet\n"); v4l2_set_ext_ctrl(s, MPEG_CID(B_FRAMES), 0, "number of B-frames"); v4l2_get_ext_ctrl(s, MPEG_CID(B_FRAMES), &s->avctx->max_b_frames, "number of B-frames"); if (s->avctx->max_b_frames == 0) return 0; avpriv_report_missing_feature(s->avctx, "DTS/PTS calculation for V4L2 encoding"); return AVERROR_PATCHWELCOME; }
static int rm_write_video(AVFormatContext *s, const uint8_t *buf, int size, int flags) { RMMuxContext *rm = s->priv_data; AVIOContext *pb = s->pb; StreamInfo *stream = rm->video_stream; int key_frame = !!(flags & AV_PKT_FLAG_KEY); /* XXX: this is incorrect: should be a parameter */ /* Well, I spent some time finding the meaning of these bits. I am not sure I understood everything, but it works !! */ #if 1 if (size > MAX_PACKET_SIZE) { avpriv_report_missing_feature(s, "Muxing packets larger than 64 kB"); return AVERROR(ENOSYS); } write_packet_header(s, stream, size + 7 + (size >= 0x4000)*4, key_frame); /* bit 7: '1' if final packet of a frame converted in several packets */ avio_w8(pb, 0x81); /* bit 7: '1' if I frame. bits 6..0 : sequence number in current frame starting from 1 */ if (key_frame) { avio_w8(pb, 0x81); } else { avio_w8(pb, 0x01); } if(size >= 0x4000){ avio_wb32(pb, size); /* total frame size */ avio_wb32(pb, size); /* offset from the start or the end */ }else{ avio_wb16(pb, 0x4000 | size); /* total frame size */ avio_wb16(pb, 0x4000 | size); /* offset from the start or the end */ } #else /* full frame */ write_packet_header(s, size + 6); avio_w8(pb, 0xc0); avio_wb16(pb, 0x4000 + size); /* total frame size */ avio_wb16(pb, 0x4000 + packet_number * 126); /* position in stream */ #endif avio_w8(pb, stream->nb_frames & 0xff); avio_write(pb, buf, size); stream->nb_frames++; return 0; }
static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size) { VP56RangeCoder *c = &s->c; int parse_filter_info = 0; int coeff_offset = 0; int vrt_shift = 0; int sub_version; int rows, cols; int res = 0; int separated_coeff = buf[0] & 1; s->frames[VP56_FRAME_CURRENT]->key_frame = !(buf[0] & 0x80); ff_vp56_init_dequant(s, (buf[0] >> 1) & 0x3F); if (s->frames[VP56_FRAME_CURRENT]->key_frame) { sub_version = buf[1] >> 3; if (sub_version > 8) return AVERROR_INVALIDDATA; s->filter_header = buf[1] & 0x06; if (buf[1] & 1) { avpriv_report_missing_feature(s->avctx, "Interlacing"); return AVERROR_PATCHWELCOME; } if (separated_coeff || !s->filter_header) { coeff_offset = AV_RB16(buf+2) - 2; buf += 2; buf_size -= 2; } rows = buf[2]; /* number of stored macroblock rows */ cols = buf[3]; /* number of stored macroblock cols */ /* buf[4] is number of displayed macroblock rows */ /* buf[5] is number of displayed macroblock cols */ if (!rows || !cols) { av_log(s->avctx, AV_LOG_ERROR, "Invalid size %dx%d\n", cols << 4, rows << 4); return AVERROR_INVALIDDATA; } if (!s->macroblocks || /* first frame */ 16*cols != s->avctx->coded_width || 16*rows != s->avctx->coded_height) { avcodec_set_dimensions(s->avctx, 16*cols, 16*rows); if (s->avctx->extradata_size == 1) { s->avctx->width -= s->avctx->extradata[0] >> 4; s->avctx->height -= s->avctx->extradata[0] & 0x0F; }
static int write_header(AVFormatContext *s) { AVCodecContext *codec = s->streams[0]->codec; if (s->nb_streams > 1) { av_log(s, AV_LOG_ERROR, "only one stream is supported\n"); return AVERROR(EINVAL); } if (codec->codec_id != AV_CODEC_ID_WAVPACK) { av_log(s, AV_LOG_ERROR, "unsupported codec\n"); return AVERROR(EINVAL); } if (codec->extradata_size > 0) { avpriv_report_missing_feature(s, "remuxing from matroska container"); return AVERROR_PATCHWELCOME; } avpriv_set_pts_info(s->streams[0], 64, 1, codec->sample_rate); return 0; }
static int parse_fmtp_config(AVStream *st, const char *value) { int len = ff_hex_to_data(NULL, value), i, ret = 0; BitstreamContext bc; uint8_t *config; int audio_mux_version, same_time_framing, num_programs, num_layers; /* Pad this buffer, too, to avoid out of bounds reads with get_bits below */ config = av_mallocz(len + AV_INPUT_BUFFER_PADDING_SIZE); if (!config) return AVERROR(ENOMEM); ff_hex_to_data(config, value); bitstream_init8(&bc, config, len); audio_mux_version = bitstream_read(&bc, 1); same_time_framing = bitstream_read(&bc, 1); bitstream_skip(&bc, 6); /* num_sub_frames */ num_programs = bitstream_read(&bc, 4); num_layers = bitstream_read(&bc, 3); if (audio_mux_version != 0 || same_time_framing != 1 || num_programs != 0 || num_layers != 0) { avpriv_report_missing_feature(NULL, "LATM config (%d,%d,%d,%d)", audio_mux_version, same_time_framing, num_programs, num_layers); ret = AVERROR_PATCHWELCOME; goto end; } av_freep(&st->codecpar->extradata); st->codecpar->extradata_size = (bitstream_bits_left(&bc) + 7) / 8; st->codecpar->extradata = av_mallocz(st->codecpar->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); if (!st->codecpar->extradata) { ret = AVERROR(ENOMEM); goto end; } for (i = 0; i < st->codecpar->extradata_size; i++) st->codecpar->extradata[i] = bitstream_read(&bc, 8); end: av_free(config); return ret; }
static int rso_write_header(AVFormatContext *s) { AVIOContext *pb = s->pb; AVCodecParameters *par = s->streams[0]->codecpar; if (!par->codec_tag) return AVERROR_INVALIDDATA; if (par->channels != 1) { av_log(s, AV_LOG_ERROR, "RSO only supports mono\n"); return AVERROR_INVALIDDATA; } if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL)) { av_log(s, AV_LOG_ERROR, "muxer does not support non seekable output\n"); return AVERROR_INVALIDDATA; } /* XXX: find legal sample rates (if any) */ if (par->sample_rate >= 1u<<16) { av_log(s, AV_LOG_ERROR, "Sample rate must be < 65536\n"); return AVERROR_INVALIDDATA; } if (par->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV) { avpriv_report_missing_feature(s, "ADPCM in RSO"); return AVERROR_PATCHWELCOME; } /* format header */ avio_wb16(pb, par->codec_tag); /* codec ID */ avio_wb16(pb, 0); /* data size, will be written at EOF */ avio_wb16(pb, par->sample_rate); avio_wb16(pb, 0x0000); /* play mode ? (0x0000 = don't loop) */ avio_flush(pb); return 0; }
static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size) { VP56RangeCoder *c = &s->c; int parse_filter_info = 0; int coeff_offset = 0; int vrt_shift = 0; int sub_version; int rows, cols; int res = 0; int separated_coeff = buf[0] & 1; s->frames[VP56_FRAME_CURRENT]->key_frame = !(buf[0] & 0x80); ff_vp56_init_dequant(s, (buf[0] >> 1) & 0x3F); if (s->frames[VP56_FRAME_CURRENT]->key_frame) { sub_version = buf[1] >> 3; if (sub_version > 8) return AVERROR_INVALIDDATA; s->filter_header = buf[1] & 0x06; if (buf[1] & 1) { avpriv_report_missing_feature(s->avctx, "Interlacing"); return AVERROR_PATCHWELCOME; } if (separated_coeff || !s->filter_header) { coeff_offset = AV_RB16(buf+2) - 2; buf += 2; buf_size -= 2; } rows = buf[2]; /* number of stored macroblock rows */ cols = buf[3]; /* number of stored macroblock cols */ /* buf[4] is number of displayed macroblock rows */ /* buf[5] is number of displayed macroblock cols */ if (!rows || !cols) { av_log(s->avctx, AV_LOG_ERROR, "Invalid size %dx%d\n", cols << 4, rows << 4); return AVERROR_INVALIDDATA; } if (!s->macroblocks || /* first frame */ 16*cols != s->avctx->coded_width || 16*rows != s->avctx->coded_height) { if (s->avctx->extradata_size == 0 && FFALIGN(s->avctx->width, 16) == 16 * cols && FFALIGN(s->avctx->height, 16) == 16 * rows) { // We assume this is properly signalled container cropping, // in an F4V file. Just set the coded_width/height, don't // touch the cropped ones. s->avctx->coded_width = 16 * cols; s->avctx->coded_height = 16 * rows; } else { int ret = ff_set_dimensions(s->avctx, 16 * cols, 16 * rows); if (ret < 0) return ret; if (s->avctx->extradata_size == 1) { s->avctx->width -= s->avctx->extradata[0] >> 4; s->avctx->height -= s->avctx->extradata[0] & 0x0F; } } res = VP56_SIZE_CHANGE; }
static int jpeg_parse_packet(AVFormatContext *ctx, PayloadContext *jpeg, AVStream *st, AVPacket *pkt, uint32_t *timestamp, const uint8_t *buf, int len, uint16_t seq, int flags) { uint8_t type, q, width, height; const uint8_t *qtables = NULL; uint16_t qtable_len; uint32_t off; int ret; if (len < 8) { av_log(ctx, AV_LOG_ERROR, "Too short RTP/JPEG packet.\n"); return AVERROR_INVALIDDATA; } /* Parse the main JPEG header. */ off = AV_RB24(buf + 1); /* fragment byte offset */ type = AV_RB8(buf + 4); /* id of jpeg decoder params */ q = AV_RB8(buf + 5); /* quantization factor (or table id) */ width = AV_RB8(buf + 6); /* frame width in 8 pixel blocks */ height = AV_RB8(buf + 7); /* frame height in 8 pixel blocks */ buf += 8; len -= 8; if (type > 1) { avpriv_report_missing_feature(ctx, "RTP/JPEG type %"PRIu8, type); return AVERROR_PATCHWELCOME; } /* Parse the quantization table header. */ if (off == 0) { /* Start of JPEG data packet. */ uint8_t new_qtables[128]; uint8_t hdr[1024]; if (q > 127) { uint8_t precision; if (len < 4) { av_log(ctx, AV_LOG_ERROR, "Too short RTP/JPEG packet.\n"); return AVERROR_INVALIDDATA; } /* The first byte is reserved for future use. */ precision = AV_RB8(buf + 1); /* size of coefficients */ qtable_len = AV_RB16(buf + 2); /* length in bytes */ buf += 4; len -= 4; if (precision) av_log(ctx, AV_LOG_WARNING, "Only 8-bit precision is supported.\n"); if (qtable_len > 0) { if (len < qtable_len) { av_log(ctx, AV_LOG_ERROR, "Too short RTP/JPEG packet.\n"); return AVERROR_INVALIDDATA; } qtables = buf; buf += qtable_len; len -= qtable_len; if (q < 255) { if (jpeg->qtables_len[q - 128] && (jpeg->qtables_len[q - 128] != qtable_len || memcmp(qtables, &jpeg->qtables[q - 128][0], qtable_len))) { av_log(ctx, AV_LOG_WARNING, "Quantization tables for q=%d changed\n", q); } else if (!jpeg->qtables_len[q - 128] && qtable_len <= 128) { memcpy(&jpeg->qtables[q - 128][0], qtables, qtable_len); jpeg->qtables_len[q - 128] = qtable_len; } } } else { if (q == 255) { av_log(ctx, AV_LOG_ERROR, "Invalid RTP/JPEG packet. Quantization tables not found.\n"); return AVERROR_INVALIDDATA; } if (!jpeg->qtables_len[q - 128]) { av_log(ctx, AV_LOG_ERROR, "No quantization tables known for q=%d yet.\n", q); return AVERROR_INVALIDDATA; } qtables = &jpeg->qtables[q - 128][0]; qtable_len = jpeg->qtables_len[q - 128]; } } else { /* q <= 127 */ if (q == 0 || q > 99) { av_log(ctx, AV_LOG_ERROR, "Reserved q value %d\n", q); return AVERROR_INVALIDDATA; } create_default_qtables(new_qtables, q); qtables = new_qtables; qtable_len = sizeof(new_qtables); } /* Skip the current frame in case of the end packet * has been lost somewhere. */ ffio_free_dyn_buf(&jpeg->frame); if ((ret = avio_open_dyn_buf(&jpeg->frame)) < 0) return ret; jpeg->timestamp = *timestamp; /* Generate a frame and scan headers that can be prepended to the * RTP/JPEG data payload to produce a JPEG compressed image in * interchange format. */ jpeg->hdr_size = jpeg_create_header(hdr, sizeof(hdr), type, width, height, qtables, qtable_len / 64); /* Copy JPEG header to frame buffer. */ avio_write(jpeg->frame, hdr, jpeg->hdr_size); } if (!jpeg->frame) { av_log(ctx, AV_LOG_ERROR, "Received packet without a start chunk; dropping frame.\n"); return AVERROR(EAGAIN); } if (jpeg->timestamp != *timestamp) { /* Skip the current frame if timestamp is incorrect. * A start packet has been lost somewhere. */ ffio_free_dyn_buf(&jpeg->frame); av_log(ctx, AV_LOG_ERROR, "RTP timestamps don't match.\n"); return AVERROR_INVALIDDATA; } if (off != avio_tell(jpeg->frame) - jpeg->hdr_size) { av_log(ctx, AV_LOG_ERROR, "Missing packets; dropping frame.\n"); return AVERROR(EAGAIN); } /* Copy data to frame buffer. */ avio_write(jpeg->frame, buf, len); if (flags & RTP_FLAG_MARKER) { /* End of JPEG data packet. */ uint8_t buf[2] = { 0xff, EOI }; /* Put EOI marker. */ avio_write(jpeg->frame, buf, sizeof(buf)); /* Prepare the JPEG packet. */ if ((ret = ff_rtp_finalize_packet(pkt, &jpeg->frame, st->index)) < 0) { av_log(ctx, AV_LOG_ERROR, "Error occurred when getting frame buffer.\n"); return ret; } return 0; } return AVERROR(EAGAIN); }
static int dxv_decode(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { DXVContext *ctx = avctx->priv_data; ThreadFrame tframe; GetByteContext *gbc = &ctx->gbc; int (*decompress_tex)(AVCodecContext *avctx); uint32_t tag; int channels, size = 0, old_type = 0; int ret; bytestream2_init(gbc, avpkt->data, avpkt->size); tag = bytestream2_get_le32(gbc); switch (tag) { case MKBETAG('D', 'X', 'T', '1'): decompress_tex = dxv_decompress_dxt1; ctx->tex_funct = ctx->texdsp.dxt1_block; ctx->tex_rat = 8; ctx->tex_step = 8; av_log(avctx, AV_LOG_DEBUG, "DXTR1 compression and DXT1 texture "); break; case MKBETAG('D', 'X', 'T', '5'): decompress_tex = dxv_decompress_dxt5; ctx->tex_funct = ctx->texdsp.dxt5_block; ctx->tex_rat = 4; ctx->tex_step = 16; av_log(avctx, AV_LOG_DEBUG, "DXTR5 compression and DXT5 texture "); break; case MKBETAG('Y', 'C', 'G', '6'): case MKBETAG('Y', 'G', '1', '0'): avpriv_report_missing_feature(avctx, "Tag 0x%08X", tag); return AVERROR_PATCHWELCOME; default: /* Old version does not have a real header, just size and type. */ size = tag & 0x00FFFFFF; old_type = tag >> 24; channels = old_type & 0x0F; if (old_type & 0x40) { av_log(avctx, AV_LOG_DEBUG, "LZF compression and DXT5 texture "); ctx->tex_funct = ctx->texdsp.dxt5_block; ctx->tex_step = 16; } else if (old_type & 0x20) { av_log(avctx, AV_LOG_DEBUG, "LZF compression and DXT1 texture "); ctx->tex_funct = ctx->texdsp.dxt1_block; ctx->tex_step = 8; } else { av_log(avctx, AV_LOG_ERROR, "Unsupported header (0x%08X)\n.", tag); return AVERROR_INVALIDDATA; } decompress_tex = dxv_decompress_lzf; ctx->tex_rat = 1; break; } /* New header is 12 bytes long. */ if (!old_type) { channels = bytestream2_get_byte(gbc); bytestream2_skip(gbc, 3); // unknown size = bytestream2_get_le32(gbc); } av_log(avctx, AV_LOG_DEBUG, "(%d channels)\n", channels); if (size != bytestream2_get_bytes_left(gbc)) { av_log(avctx, AV_LOG_ERROR, "Incomplete or invalid file (%u > %u)\n.", size, bytestream2_get_bytes_left(gbc)); return AVERROR_INVALIDDATA; } ctx->tex_size = avctx->coded_width * avctx->coded_height * 4 / ctx->tex_rat; ret = av_reallocp(&ctx->tex_data, ctx->tex_size); if (ret < 0) return ret; /* Decompress texture out of the intermediate compression. */ ret = decompress_tex(avctx); if (ret < 0) return ret; tframe.f = data; ret = ff_thread_get_buffer(avctx, &tframe, 0); if (ret < 0) return ret; ff_thread_finish_setup(avctx); /* Now decompress the texture with the standard functions. */ avctx->execute2(avctx, decompress_texture_thread, tframe.f, NULL, ctx->slice_count); /* Frame is ready to be output. */ tframe.f->pict_type = AV_PICTURE_TYPE_I; tframe.f->key_frame = 1; *got_frame = 1; return avpkt->size; }
/** * This filter creates an MPEG-4 AudioSpecificConfig from an MPEG-2/4 * ADTS header and removes the ADTS header. */ static int aac_adtstoasc_filter(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const char *args, uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size, int keyframe) { GetBitContext gb; PutBitContext pb; AACADTSHeaderInfo hdr; AACBSFContext *ctx = bsfc->priv_data; init_get_bits(&gb, buf, AAC_ADTS_HEADER_SIZE*8); *poutbuf = (uint8_t*) buf; *poutbuf_size = buf_size; if (avctx->extradata) if (show_bits(&gb, 12) != 0xfff) return 0; if (avpriv_aac_parse_header(&gb, &hdr) < 0) { av_log(avctx, AV_LOG_ERROR, "Error parsing ADTS frame header!\n"); return -1; } if (!hdr.crc_absent && hdr.num_aac_frames > 1) { avpriv_report_missing_feature(avctx, "Multiple RDBs per frame with CRC"); return AVERROR_PATCHWELCOME; } buf += AAC_ADTS_HEADER_SIZE + 2*!hdr.crc_absent; buf_size -= AAC_ADTS_HEADER_SIZE + 2*!hdr.crc_absent; if (!ctx->first_frame_done) { int pce_size = 0; uint8_t pce_data[MAX_PCE_SIZE]; if (!hdr.chan_config) { init_get_bits(&gb, buf, buf_size * 8); if (get_bits(&gb, 3) != 5) { avpriv_report_missing_feature(avctx, "PCE-based channel configuration " "without PCE as first syntax " "element"); return AVERROR_PATCHWELCOME; } init_put_bits(&pb, pce_data, MAX_PCE_SIZE); pce_size = avpriv_copy_pce_data(&pb, &gb)/8; flush_put_bits(&pb); buf_size -= get_bits_count(&gb)/8; buf += get_bits_count(&gb)/8; } avctx->extradata_size = 2 + pce_size; avctx->extradata = av_mallocz(avctx->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); init_put_bits(&pb, avctx->extradata, avctx->extradata_size); put_bits(&pb, 5, hdr.object_type); put_bits(&pb, 4, hdr.sampling_index); put_bits(&pb, 4, hdr.chan_config); put_bits(&pb, 1, 0); //frame length - 1024 samples put_bits(&pb, 1, 0); //does not depend on core coder put_bits(&pb, 1, 0); //is not extension flush_put_bits(&pb); if (pce_size) { memcpy(avctx->extradata + 2, pce_data, pce_size); } ctx->first_frame_done = 1; } *poutbuf = (uint8_t*) buf; *poutbuf_size = buf_size; return 0; }
static int mpegaudio_parse(AVCodecParserContext *s1, AVCodecContext *avctx, const uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size) { MpegAudioParseContext *s = s1->priv_data; ParseContext *pc = &s->pc; uint32_t state= pc->state; int i; int next= END_NOT_FOUND; int flush = !buf_size; for(i=0; i<buf_size; ){ if(s->frame_size){ int inc= FFMIN(buf_size - i, s->frame_size); i += inc; s->frame_size -= inc; state = 0; if(!s->frame_size){ next= i; break; } }else{ while(i<buf_size){ int ret, sr, channels, bit_rate, frame_size; enum AVCodecID codec_id = avctx->codec_id; state= (state<<8) + buf[i++]; ret = ff_mpa_decode_header(state, &sr, &channels, &frame_size, &bit_rate, &codec_id); if (ret < 4) { if (i > 4) s->header_count = -2; } else { int header_threshold = avctx->codec_id != AV_CODEC_ID_NONE && avctx->codec_id != codec_id; if((state&SAME_HEADER_MASK) != (s->header&SAME_HEADER_MASK) && s->header) s->header_count= -3; s->header= state; s->header_count++; s->frame_size = ret-4; if (s->header_count > header_threshold) { avctx->sample_rate= sr; avctx->channels = channels; s1->duration = frame_size; avctx->codec_id = codec_id; if (s->no_bitrate || !avctx->bit_rate) { s->no_bitrate = 1; avctx->bit_rate += (bit_rate - avctx->bit_rate) / (s->header_count - header_threshold); } } if (s1->flags & PARSER_FLAG_COMPLETE_FRAMES) { s->frame_size = 0; next = buf_size; } else if (codec_id == AV_CODEC_ID_MP3ADU) { avpriv_report_missing_feature(avctx, "MP3ADU full parser"); *poutbuf = NULL; *poutbuf_size = 0; return buf_size; /* parsers must not return error codes */ } break; } } } } pc->state= state; if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) { *poutbuf = NULL; *poutbuf_size = 0; return buf_size; } if (flush && buf_size >= ID3v1_TAG_SIZE && memcmp(buf, "TAG", 3) == 0) { *poutbuf = NULL; *poutbuf_size = 0; return next; } if (flush && buf_size >= APE_TAG_FOOTER_BYTES && memcmp(buf, APE_TAG_PREAMBLE, 8) == 0) { *poutbuf = NULL; *poutbuf_size = 0; return next; } *poutbuf = buf; *poutbuf_size = buf_size; return next; }
static int wv_read_block_header(AVFormatContext *ctx, AVIOContext *pb) { WVContext *wc = ctx->priv_data; int ret; int rate, bpp, chan; uint32_t chmask, flags; wc->pos = avio_tell(pb); /* don't return bogus packets with the ape tag data */ if (wc->apetag_start && wc->pos >= wc->apetag_start) return AVERROR_EOF; ret = avio_read(pb, wc->block_header, WV_HEADER_SIZE); if (ret != WV_HEADER_SIZE) return (ret < 0) ? ret : AVERROR_EOF; ret = ff_wv_parse_header(&wc->header, wc->block_header); if (ret < 0) { av_log(ctx, AV_LOG_ERROR, "Invalid block header.\n"); return ret; } if (wc->header.flags & WV_DSD) { avpriv_report_missing_feature(ctx, "WV DSD"); return AVERROR_PATCHWELCOME; } if (wc->header.version < 0x402 || wc->header.version > 0x410) { avpriv_report_missing_feature(ctx, "WV version 0x%03X", wc->header.version); return AVERROR_PATCHWELCOME; } /* Blocks with zero samples don't contain actual audio information * and should be ignored */ if (!wc->header.samples) return 0; // parse flags flags = wc->header.flags; bpp = ((flags & 3) + 1) << 3; chan = 1 + !(flags & WV_MONO); chmask = flags & WV_MONO ? AV_CH_LAYOUT_MONO : AV_CH_LAYOUT_STEREO; rate = wv_rates[(flags >> 23) & 0xF]; wc->multichannel = !(wc->header.initial && wc->header.final); if (wc->multichannel) { chan = wc->chan; chmask = wc->chmask; } if ((rate == -1 || !chan) && !wc->block_parsed) { int64_t block_end = avio_tell(pb) + wc->header.blocksize; if (!(pb->seekable & AVIO_SEEKABLE_NORMAL)) { av_log(ctx, AV_LOG_ERROR, "Cannot determine additional parameters\n"); return AVERROR_INVALIDDATA; } while (avio_tell(pb) < block_end && !avio_feof(pb)) { int id, size; id = avio_r8(pb); size = (id & 0x80) ? avio_rl24(pb) : avio_r8(pb); size <<= 1; if (id & 0x40) size--; switch (id & 0x3F) { case 0xD: if (size <= 1) { av_log(ctx, AV_LOG_ERROR, "Insufficient channel information\n"); return AVERROR_INVALIDDATA; } chan = avio_r8(pb); switch (size - 2) { case 0: chmask = avio_r8(pb); break; case 1: chmask = avio_rl16(pb); break; case 2: chmask = avio_rl24(pb); break; case 3: chmask = avio_rl32(pb); break; case 4: avio_skip(pb, 1); chan |= (avio_r8(pb) & 0xF) << 8; chan += 1; chmask = avio_rl24(pb); break; case 5: avio_skip(pb, 1); chan |= (avio_r8(pb) & 0xF) << 8; chan += 1; chmask = avio_rl32(pb); break; default: av_log(ctx, AV_LOG_ERROR, "Invalid channel info size %d\n", size); return AVERROR_INVALIDDATA; } break; case 0x27: rate = avio_rl24(pb); break; default: avio_skip(pb, size); } if (id & 0x40) avio_skip(pb, 1); } if (rate == -1) { av_log(ctx, AV_LOG_ERROR, "Cannot determine custom sampling rate\n"); return AVERROR_INVALIDDATA; } avio_seek(pb, block_end - wc->header.blocksize, SEEK_SET); } if (!wc->bpp) wc->bpp = bpp; if (!wc->chan) wc->chan = chan; if (!wc->chmask) wc->chmask = chmask; if (!wc->rate) wc->rate = rate; if (flags && bpp != wc->bpp) { av_log(ctx, AV_LOG_ERROR, "Bits per sample differ, this block: %i, header block: %i\n", bpp, wc->bpp); return AVERROR_INVALIDDATA; } if (flags && !wc->multichannel && chan != wc->chan) { av_log(ctx, AV_LOG_ERROR, "Channels differ, this block: %i, header block: %i\n", chan, wc->chan); return AVERROR_INVALIDDATA; } if (flags && rate != -1 && rate != wc->rate) { av_log(ctx, AV_LOG_ERROR, "Sampling rate differ, this block: %i, header block: %i\n", rate, wc->rate); return AVERROR_INVALIDDATA; } return 0; }
static int dxv_decode(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { DXVContext *ctx = avctx->priv_data; ThreadFrame tframe; GetByteContext *gbc = &ctx->gbc; int (*decompress_tex)(AVCodecContext *avctx); const char *msgcomp, *msgtext; uint32_t tag; int version_major, version_minor = 0; int size = 0, old_type = 0; int ret; bytestream2_init(gbc, avpkt->data, avpkt->size); tag = bytestream2_get_le32(gbc); switch (tag) { case MKBETAG('D', 'X', 'T', '1'): decompress_tex = dxv_decompress_dxt1; ctx->tex_funct = ctx->texdsp.dxt1_block; ctx->tex_rat = 8; ctx->tex_step = 8; msgcomp = "DXTR1"; msgtext = "DXT1"; break; case MKBETAG('D', 'X', 'T', '5'): decompress_tex = dxv_decompress_dxt5; ctx->tex_funct = ctx->texdsp.dxt5_block; ctx->tex_rat = 4; ctx->tex_step = 16; msgcomp = "DXTR5"; msgtext = "DXT5"; break; case MKBETAG('Y', 'C', 'G', '6'): case MKBETAG('Y', 'G', '1', '0'): avpriv_report_missing_feature(avctx, "Tag 0x%08X", tag); return AVERROR_PATCHWELCOME; default: /* Old version does not have a real header, just size and type. */ size = tag & 0x00FFFFFF; old_type = tag >> 24; version_major = (old_type & 0x0F) - 1; if (old_type & 0x80) { msgcomp = "RAW"; decompress_tex = dxv_decompress_raw; } else { msgcomp = "LZF"; decompress_tex = dxv_decompress_lzf; } if (old_type & 0x40) { msgtext = "DXT5"; ctx->tex_funct = ctx->texdsp.dxt5_block; ctx->tex_step = 16; } else if (old_type & 0x20 || version_major == 1) { msgtext = "DXT1"; ctx->tex_funct = ctx->texdsp.dxt1_block; ctx->tex_step = 8; } else { av_log(avctx, AV_LOG_ERROR, "Unsupported header (0x%08X)\n.", tag); return AVERROR_INVALIDDATA; } ctx->tex_rat = 1; break; } /* New header is 12 bytes long. */ if (!old_type) { version_major = bytestream2_get_byte(gbc) - 1; version_minor = bytestream2_get_byte(gbc); /* Encoder copies texture data when compression is not advantageous. */ if (bytestream2_get_byte(gbc)) { msgcomp = "RAW"; ctx->tex_rat = 1; decompress_tex = dxv_decompress_raw; } bytestream2_skip(gbc, 1); // unknown size = bytestream2_get_le32(gbc); } av_log(avctx, AV_LOG_DEBUG, "%s compression with %s texture (version %d.%d)\n", msgcomp, msgtext, version_major, version_minor); if (size != bytestream2_get_bytes_left(gbc)) { av_log(avctx, AV_LOG_ERROR, "Incomplete or invalid file (header %d, left %d).\n", size, bytestream2_get_bytes_left(gbc)); return AVERROR_INVALIDDATA; } ctx->tex_size = avctx->coded_width * avctx->coded_height * 4 / ctx->tex_rat; ret = av_reallocp(&ctx->tex_data, ctx->tex_size); if (ret < 0) return ret; /* Decompress texture out of the intermediate compression. */ ret = decompress_tex(avctx); if (ret < 0) return ret; tframe.f = data; ret = ff_thread_get_buffer(avctx, &tframe, 0); if (ret < 0) return ret; ff_thread_finish_setup(avctx); /* Now decompress the texture with the standard functions. */ avctx->execute2(avctx, decompress_texture_thread, tframe.f, NULL, ctx->slice_count); /* Frame is ready to be output. */ tframe.f->pict_type = AV_PICTURE_TYPE_I; tframe.f->key_frame = 1; *got_frame = 1; return avpkt->size; }
int ff_spdif_read_packet(AVFormatContext *s, AVPacket *pkt) { AVIOContext *pb = s->pb; enum IEC61937DataType data_type; enum AVCodecID codec_id; uint32_t state = 0; int pkt_size_bits, offset, ret; while (state != (AV_BSWAP16C(SYNCWORD1) << 16 | AV_BSWAP16C(SYNCWORD2))) { state = (state << 8) | avio_r8(pb); if (avio_feof(pb)) return AVERROR_EOF; } data_type = avio_rl16(pb); pkt_size_bits = avio_rl16(pb); if (pkt_size_bits % 16) avpriv_request_sample(s, "Packet not ending at a 16-bit boundary"); ret = av_new_packet(pkt, FFALIGN(pkt_size_bits, 16) >> 3); if (ret) return ret; pkt->pos = avio_tell(pb) - BURST_HEADER_SIZE; if (avio_read(pb, pkt->data, pkt->size) < pkt->size) { av_free_packet(pkt); return AVERROR_EOF; } ff_spdif_bswap_buf16((uint16_t *)pkt->data, (uint16_t *)pkt->data, pkt->size >> 1); ret = spdif_get_offset_and_codec(s, data_type, pkt->data, &offset, &codec_id); if (ret) { av_free_packet(pkt); return ret; } /* skip over the padding to the beginning of the next frame */ avio_skip(pb, offset - pkt->size - BURST_HEADER_SIZE); if (!s->nb_streams) { /* first packet, create a stream */ AVStream *st = avformat_new_stream(s, NULL); if (!st) { av_free_packet(pkt); return AVERROR(ENOMEM); } st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_id = codec_id; } else if (codec_id != s->streams[0]->codec->codec_id) { avpriv_report_missing_feature(s, "Codec change in IEC 61937"); return AVERROR_PATCHWELCOME; } if (!s->bit_rate && s->streams[0]->codec->sample_rate) /* stream bitrate matches 16-bit stereo PCM bitrate for currently supported codecs */ s->bit_rate = 2 * 16 * s->streams[0]->codec->sample_rate; return 0; }
static int tiff_decode_tag(TiffContext *s, AVFrame *frame) { unsigned tag, type, count, off, value = 0, value2 = 0; int i, start; int pos; int ret; double *dp; ret = ff_tread_tag(&s->gb, s->le, &tag, &type, &count, &start); if (ret < 0) { goto end; } off = bytestream2_tell(&s->gb); if (count == 1) { switch (type) { case TIFF_BYTE: case TIFF_SHORT: case TIFF_LONG: value = ff_tget(&s->gb, type, s->le); break; case TIFF_RATIONAL: value = ff_tget(&s->gb, TIFF_LONG, s->le); value2 = ff_tget(&s->gb, TIFF_LONG, s->le); break; case TIFF_STRING: if (count <= 4) { break; } default: value = UINT_MAX; } } switch (tag) { case TIFF_WIDTH: s->width = value; break; case TIFF_HEIGHT: s->height = value; break; case TIFF_BPP: s->bppcount = count; if (count > 4) { av_log(s->avctx, AV_LOG_ERROR, "This format is not supported (bpp=%d, %d components)\n", s->bpp, count); return AVERROR_INVALIDDATA; } if (count == 1) s->bpp = value; else { switch (type) { case TIFF_BYTE: case TIFF_SHORT: case TIFF_LONG: s->bpp = 0; if (bytestream2_get_bytes_left(&s->gb) < type_sizes[type] * count) return AVERROR_INVALIDDATA; for (i = 0; i < count; i++) s->bpp += ff_tget(&s->gb, type, s->le); break; default: s->bpp = -1; } } break; case TIFF_SAMPLES_PER_PIXEL: if (count != 1) { av_log(s->avctx, AV_LOG_ERROR, "Samples per pixel requires a single value, many provided\n"); return AVERROR_INVALIDDATA; } if (value > 4U) { av_log(s->avctx, AV_LOG_ERROR, "Samples per pixel %d is too large\n", value); return AVERROR_INVALIDDATA; } if (s->bppcount == 1) s->bpp *= value; s->bppcount = value; break; case TIFF_COMPR: s->compr = value; s->predictor = 0; switch (s->compr) { case TIFF_RAW: case TIFF_PACKBITS: case TIFF_LZW: case TIFF_CCITT_RLE: break; case TIFF_G3: case TIFF_G4: s->fax_opts = 0; break; case TIFF_DEFLATE: case TIFF_ADOBE_DEFLATE: #if CONFIG_ZLIB break; #else av_log(s->avctx, AV_LOG_ERROR, "Deflate: ZLib not compiled in\n"); return AVERROR(ENOSYS); #endif case TIFF_JPEG: case TIFF_NEWJPEG: avpriv_report_missing_feature(s->avctx, "JPEG compression"); return AVERROR_PATCHWELCOME; default: av_log(s->avctx, AV_LOG_ERROR, "Unknown compression method %i\n", s->compr); return AVERROR_INVALIDDATA; } break; case TIFF_ROWSPERSTRIP: if (!value || (type == TIFF_LONG && value == UINT_MAX)) value = s->height; s->rps = FFMIN(value, s->height); break; case TIFF_STRIP_OFFS: if (count == 1) { s->strippos = 0; s->stripoff = value; } else s->strippos = off; s->strips = count; if (s->strips == 1) s->rps = s->height; s->sot = type; break; case TIFF_STRIP_SIZE: if (count == 1) { s->stripsizesoff = 0; s->stripsize = value; s->strips = 1; } else { s->stripsizesoff = off; } s->strips = count; s->sstype = type; break; case TIFF_XRES: case TIFF_YRES: set_sar(s, tag, value, value2); break; case TIFF_TILE_BYTE_COUNTS: case TIFF_TILE_LENGTH: case TIFF_TILE_OFFSETS: case TIFF_TILE_WIDTH: av_log(s->avctx, AV_LOG_ERROR, "Tiled images are not supported\n"); return AVERROR_PATCHWELCOME; break; case TIFF_PREDICTOR: s->predictor = value; break; case TIFF_PHOTOMETRIC: switch (value) { case TIFF_PHOTOMETRIC_WHITE_IS_ZERO: case TIFF_PHOTOMETRIC_BLACK_IS_ZERO: case TIFF_PHOTOMETRIC_RGB: case TIFF_PHOTOMETRIC_PALETTE: case TIFF_PHOTOMETRIC_YCBCR: s->photometric = value; break; case TIFF_PHOTOMETRIC_ALPHA_MASK: case TIFF_PHOTOMETRIC_SEPARATED: case TIFF_PHOTOMETRIC_CIE_LAB: case TIFF_PHOTOMETRIC_ICC_LAB: case TIFF_PHOTOMETRIC_ITU_LAB: case TIFF_PHOTOMETRIC_CFA: case TIFF_PHOTOMETRIC_LOG_L: case TIFF_PHOTOMETRIC_LOG_LUV: case TIFF_PHOTOMETRIC_LINEAR_RAW: avpriv_report_missing_feature(s->avctx, "PhotometricInterpretation 0x%04X", value); return AVERROR_PATCHWELCOME; default: av_log(s->avctx, AV_LOG_ERROR, "PhotometricInterpretation %u is " "unknown\n", value); return AVERROR_INVALIDDATA; } break; case TIFF_FILL_ORDER: if (value < 1 || value > 2) { av_log(s->avctx, AV_LOG_ERROR, "Unknown FillOrder value %d, trying default one\n", value); value = 1; } s->fill_order = value - 1; break; case TIFF_PAL: { GetByteContext pal_gb[3]; off = type_sizes[type]; if (count / 3 > 256 || bytestream2_get_bytes_left(&s->gb) < count / 3 * off * 3) return AVERROR_INVALIDDATA; pal_gb[0] = pal_gb[1] = pal_gb[2] = s->gb; bytestream2_skip(&pal_gb[1], count / 3 * off); bytestream2_skip(&pal_gb[2], count / 3 * off * 2); off = (type_sizes[type] - 1) << 3; for (i = 0; i < count / 3; i++) { uint32_t p = 0xFF000000; p |= (ff_tget(&pal_gb[0], type, s->le) >> off) << 16; p |= (ff_tget(&pal_gb[1], type, s->le) >> off) << 8; p |= ff_tget(&pal_gb[2], type, s->le) >> off; s->palette[i] = p; } s->palette_is_set = 1; break; } case TIFF_PLANAR: s->planar = value == 2; break; case TIFF_YCBCR_SUBSAMPLING: if (count != 2) { av_log(s->avctx, AV_LOG_ERROR, "subsample count invalid\n"); return AVERROR_INVALIDDATA; } for (i = 0; i < count; i++) s->subsampling[i] = ff_tget(&s->gb, type, s->le); break; case TIFF_T4OPTIONS: if (s->compr == TIFF_G3) s->fax_opts = value; break; case TIFF_T6OPTIONS: if (s->compr == TIFF_G4) s->fax_opts = value; break; #define ADD_METADATA(count, name, sep)\ if ((ret = add_metadata(count, type, name, sep, s, frame)) < 0) {\ av_log(s->avctx, AV_LOG_ERROR, "Error allocating temporary buffer\n");\ goto end;\ } case TIFF_MODEL_PIXEL_SCALE: ADD_METADATA(count, "ModelPixelScaleTag", NULL); break; case TIFF_MODEL_TRANSFORMATION: ADD_METADATA(count, "ModelTransformationTag", NULL); break; case TIFF_MODEL_TIEPOINT: ADD_METADATA(count, "ModelTiepointTag", NULL); break; case TIFF_GEO_KEY_DIRECTORY: ADD_METADATA(1, "GeoTIFF_Version", NULL); ADD_METADATA(2, "GeoTIFF_Key_Revision", "."); s->geotag_count = ff_tget_short(&s->gb, s->le); if (s->geotag_count > count / 4 - 1) { s->geotag_count = count / 4 - 1; av_log(s->avctx, AV_LOG_WARNING, "GeoTIFF key directory buffer shorter than specified\n"); } if (bytestream2_get_bytes_left(&s->gb) < s->geotag_count * sizeof(int16_t) * 4) { s->geotag_count = 0; return -1; } s->geotags = av_mallocz_array(s->geotag_count, sizeof(TiffGeoTag)); if (!s->geotags) { av_log(s->avctx, AV_LOG_ERROR, "Error allocating temporary buffer\n"); s->geotag_count = 0; goto end; } for (i = 0; i < s->geotag_count; i++) { s->geotags[i].key = ff_tget_short(&s->gb, s->le); s->geotags[i].type = ff_tget_short(&s->gb, s->le); s->geotags[i].count = ff_tget_short(&s->gb, s->le); if (!s->geotags[i].type) s->geotags[i].val = get_geokey_val(s->geotags[i].key, ff_tget_short(&s->gb, s->le)); else s->geotags[i].offset = ff_tget_short(&s->gb, s->le); } break; case TIFF_GEO_DOUBLE_PARAMS: if (count >= INT_MAX / sizeof(int64_t)) return AVERROR_INVALIDDATA; if (bytestream2_get_bytes_left(&s->gb) < count * sizeof(int64_t)) return AVERROR_INVALIDDATA; dp = av_malloc_array(count, sizeof(double)); if (!dp) { av_log(s->avctx, AV_LOG_ERROR, "Error allocating temporary buffer\n"); goto end; } for (i = 0; i < count; i++) dp[i] = ff_tget_double(&s->gb, s->le); for (i = 0; i < s->geotag_count; i++) { if (s->geotags[i].type == TIFF_GEO_DOUBLE_PARAMS) { if (s->geotags[i].count == 0 || s->geotags[i].offset + s->geotags[i].count > count) { av_log(s->avctx, AV_LOG_WARNING, "Invalid GeoTIFF key %d\n", s->geotags[i].key); } else { char *ap = doubles2str(&dp[s->geotags[i].offset], s->geotags[i].count, ", "); if (!ap) { av_log(s->avctx, AV_LOG_ERROR, "Error allocating temporary buffer\n"); av_freep(&dp); return AVERROR(ENOMEM); } s->geotags[i].val = ap; } } } av_freep(&dp); break; case TIFF_GEO_ASCII_PARAMS: pos = bytestream2_tell(&s->gb); for (i = 0; i < s->geotag_count; i++) { if (s->geotags[i].type == TIFF_GEO_ASCII_PARAMS) { if (s->geotags[i].count == 0 || s->geotags[i].offset + s->geotags[i].count > count) { av_log(s->avctx, AV_LOG_WARNING, "Invalid GeoTIFF key %d\n", s->geotags[i].key); } else { char *ap; bytestream2_seek(&s->gb, pos + s->geotags[i].offset, SEEK_SET); if (bytestream2_get_bytes_left(&s->gb) < s->geotags[i].count) return AVERROR_INVALIDDATA; ap = av_malloc(s->geotags[i].count); if (!ap) { av_log(s->avctx, AV_LOG_ERROR, "Error allocating temporary buffer\n"); return AVERROR(ENOMEM); } bytestream2_get_bufferu(&s->gb, ap, s->geotags[i].count); ap[s->geotags[i].count - 1] = '\0'; //replace the "|" delimiter with a 0 byte s->geotags[i].val = ap; } } } break; case TIFF_ARTIST: ADD_METADATA(count, "artist", NULL); break; case TIFF_COPYRIGHT: ADD_METADATA(count, "copyright", NULL); break; case TIFF_DATE: ADD_METADATA(count, "date", NULL); break; case TIFF_DOCUMENT_NAME: ADD_METADATA(count, "document_name", NULL); break; case TIFF_HOST_COMPUTER: ADD_METADATA(count, "computer", NULL); break; case TIFF_IMAGE_DESCRIPTION: ADD_METADATA(count, "description", NULL); break; case TIFF_MAKE: ADD_METADATA(count, "make", NULL); break; case TIFF_MODEL: ADD_METADATA(count, "model", NULL); break; case TIFF_PAGE_NAME: ADD_METADATA(count, "page_name", NULL); break; case TIFF_PAGE_NUMBER: ADD_METADATA(count, "page_number", " / "); break; case TIFF_SOFTWARE_NAME: ADD_METADATA(count, "software", NULL); break; default: if (s->avctx->err_recognition & AV_EF_EXPLODE) { av_log(s->avctx, AV_LOG_ERROR, "Unknown or unsupported tag %d/0X%0X\n", tag, tag); return AVERROR_INVALIDDATA; } } end: bytestream2_seek(&s->gb, start, SEEK_SET); return 0; }
static int decode_group3_2d_line(AVCodecContext *avctx, GetBitContext *gb, unsigned int width, int *runs, const int *runend, const int *ref) { int mode = 0, saved_run = 0, t; int run_off = *ref++; unsigned int offs = 0, run = 0; while (offs < width) { int cmode = get_vlc2(gb, ccitt_group3_2d_vlc.table, 9, 1); if (cmode == -1) { av_log(avctx, AV_LOG_ERROR, "Incorrect mode VLC\n"); return AVERROR_INVALIDDATA; } if (!cmode) { //pass mode if (run_off < width) run_off += *ref++; run = run_off - offs; offs = run_off; if (run_off < width) run_off += *ref++; if (offs > width) { av_log(avctx, AV_LOG_ERROR, "Run went out of bounds\n"); return AVERROR_INVALIDDATA; } saved_run += run; } else if (cmode == 1) { //horizontal mode int k; for (k = 0; k < 2; k++) { run = 0; for (;;) { t = get_vlc2(gb, ccitt_vlc[mode].table, 9, 2); if (t == -1) { av_log(avctx, AV_LOG_ERROR, "Incorrect code\n"); return AVERROR_INVALIDDATA; } run += t; if (t < 64) break; } *runs++ = run + saved_run; if (runs >= runend) { av_log(avctx, AV_LOG_ERROR, "Run overrun\n"); return AVERROR_INVALIDDATA; } saved_run = 0; offs += run; if (offs > width || run > width) { av_log(avctx, AV_LOG_ERROR, "Run went out of bounds\n"); return AVERROR_INVALIDDATA; } mode = !mode; } } else if (cmode == 9 || cmode == 10) { avpriv_report_missing_feature(avctx, "Special modes support"); return AVERROR_PATCHWELCOME; } else { //vertical mode run = run_off - offs + (cmode - 5); run_off -= *--ref; offs += run; if (offs > width || run > width) { av_log(avctx, AV_LOG_ERROR, "Run went out of bounds\n"); return AVERROR_INVALIDDATA; } *runs++ = run + saved_run; if (runs >= runend) { av_log(avctx, AV_LOG_ERROR, "Run overrun\n"); return AVERROR_INVALIDDATA; } saved_run = 0; mode = !mode; } //sync line pointers while (offs < width && run_off <= offs) { run_off += *ref++; run_off += *ref++; } } *runs++ = saved_run; if (saved_run) { if (runs >= runend) { av_log(avctx, AV_LOG_ERROR, "Run overrun\n"); return -1; } *runs++ = 0; } return 0; }
static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { AVFrame * const p = data; GetByteContext gbc; int colors; int w, h, ret; int ver; bytestream2_init(&gbc, avpkt->data, avpkt->size); if ( bytestream2_get_bytes_left(&gbc) >= 552 && check_header(gbc.buffer + 512, bytestream2_get_bytes_left(&gbc) - 512) ) bytestream2_skip(&gbc, 512); ver = check_header(gbc.buffer, bytestream2_get_bytes_left(&gbc)); /* smallest PICT header */ if (bytestream2_get_bytes_left(&gbc) < 40) { av_log(avctx, AV_LOG_ERROR, "Frame is too small %d\n", bytestream2_get_bytes_left(&gbc)); return AVERROR_INVALIDDATA; } bytestream2_skip(&gbc, 6); h = bytestream2_get_be16(&gbc); w = bytestream2_get_be16(&gbc); ret = ff_set_dimensions(avctx, w, h); if (ret < 0) return ret; /* version 1 is identified by 0x1101 * it uses byte-aligned opcodes rather than word-aligned */ if (ver == 1) { avpriv_request_sample(avctx, "QuickDraw version 1"); return AVERROR_PATCHWELCOME; } else if (ver != 2) { avpriv_request_sample(avctx, "QuickDraw version unknown (%X)", bytestream2_get_be32(&gbc)); return AVERROR_PATCHWELCOME; } bytestream2_skip(&gbc, 4+26); while (bytestream2_get_bytes_left(&gbc) >= 4) { int bppcnt, bpp; int rowbytes, pack_type; int opcode = bytestream2_get_be16(&gbc); switch(opcode) { case PACKBITSRECT: case PACKBITSRGN: av_log(avctx, AV_LOG_DEBUG, "Parsing Packbit opcode\n"); bytestream2_skip(&gbc, 30); bppcnt = bytestream2_get_be16(&gbc); /* cmpCount */ bpp = bytestream2_get_be16(&gbc); /* cmpSize */ av_log(avctx, AV_LOG_DEBUG, "bppcount %d bpp %d\n", bppcnt, bpp); if (bppcnt == 1 && bpp == 8) { avctx->pix_fmt = AV_PIX_FMT_PAL8; } else { av_log(avctx, AV_LOG_ERROR, "Invalid pixel format (bppcnt %d bpp %d) in Packbit\n", bppcnt, bpp); return AVERROR_INVALIDDATA; } /* jump to palette */ bytestream2_skip(&gbc, 18); colors = bytestream2_get_be16(&gbc); if (colors < 0 || colors > 256) { av_log(avctx, AV_LOG_ERROR, "Error color count - %i(0x%X)\n", colors, colors); return AVERROR_INVALIDDATA; } if (bytestream2_get_bytes_left(&gbc) < (colors + 1) * 8) { av_log(avctx, AV_LOG_ERROR, "Palette is too small %d\n", bytestream2_get_bytes_left(&gbc)); return AVERROR_INVALIDDATA; } if ((ret = ff_get_buffer(avctx, p, 0)) < 0) return ret; parse_palette(avctx, &gbc, (uint32_t *)p->data[1], colors); p->palette_has_changed = 1; /* jump to image data */ bytestream2_skip(&gbc, 18); if (opcode == PACKBITSRGN) { bytestream2_skip(&gbc, 2 + 8); /* size + rect */ avpriv_report_missing_feature(avctx, "Packbit mask region"); } ret = decode_rle(avctx, p, &gbc, bppcnt); if (ret < 0) return ret; *got_frame = 1; break; case DIRECTBITSRECT: case DIRECTBITSRGN: av_log(avctx, AV_LOG_DEBUG, "Parsing Directbit opcode\n"); bytestream2_skip(&gbc, 4); rowbytes = bytestream2_get_be16(&gbc) & 0x3FFF; if (rowbytes <= 250) { avpriv_report_missing_feature(avctx, "Short rowbytes"); return AVERROR_PATCHWELCOME; } bytestream2_skip(&gbc, 10); pack_type = bytestream2_get_be16(&gbc); bytestream2_skip(&gbc, 16); bppcnt = bytestream2_get_be16(&gbc); /* cmpCount */ bpp = bytestream2_get_be16(&gbc); /* cmpSize */ av_log(avctx, AV_LOG_DEBUG, "bppcount %d bpp %d\n", bppcnt, bpp); if (bppcnt == 3 && bpp == 8) { avctx->pix_fmt = AV_PIX_FMT_RGB24; } else if (bppcnt == 4 && bpp == 8) { avctx->pix_fmt = AV_PIX_FMT_ARGB; } else { av_log(avctx, AV_LOG_ERROR, "Invalid pixel format (bppcnt %d bpp %d) in Directbit\n", bppcnt, bpp); return AVERROR_INVALIDDATA; } /* set packing when default is selected */ if (pack_type == 0) pack_type = bppcnt; if (pack_type != 3 && pack_type != 4) { avpriv_request_sample(avctx, "Pack type %d", pack_type); return AVERROR_PATCHWELCOME; } if ((ret = ff_get_buffer(avctx, p, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } /* jump to data */ bytestream2_skip(&gbc, 30); if (opcode == DIRECTBITSRGN) { bytestream2_skip(&gbc, 2 + 8); /* size + rect */ avpriv_report_missing_feature(avctx, "DirectBit mask region"); } ret = decode_rle(avctx, p, &gbc, bppcnt); if (ret < 0) return ret; *got_frame = 1; break; default: av_log(avctx, AV_LOG_TRACE, "Unknown 0x%04X opcode\n", opcode); break; } /* exit the loop when a known pixel block has been found */ if (*got_frame) { int eop, trail; /* re-align to a word */ bytestream2_skip(&gbc, bytestream2_get_bytes_left(&gbc) % 2); eop = bytestream2_get_be16(&gbc); trail = bytestream2_get_bytes_left(&gbc); if (eop != EOP) av_log(avctx, AV_LOG_WARNING, "Missing end of picture opcode (found 0x%04X)\n", eop); if (trail) av_log(avctx, AV_LOG_WARNING, "Got %d trailing bytes\n", trail); break; } } if (*got_frame) { p->pict_type = AV_PICTURE_TYPE_I; p->key_frame = 1; return avpkt->size; } else { av_log(avctx, AV_LOG_ERROR, "Frame contained no usable data\n"); return AVERROR_INVALIDDATA; } }
static int vfw_read_header(AVFormatContext *s) { struct vfw_ctx *ctx = s->priv_data; AVCodecParameters *par; AVStream *st; int devnum; int bisize; BITMAPINFO *bi; CAPTUREPARMS cparms; DWORD biCompression; WORD biBitCount; int ret; AVRational framerate_q; if (!strcmp(s->filename, "list")) { for (devnum = 0; devnum <= 9; devnum++) { char driver_name[256]; char driver_ver[256]; ret = capGetDriverDescription(devnum, driver_name, sizeof(driver_name), driver_ver, sizeof(driver_ver)); if (ret) { av_log(s, AV_LOG_INFO, "Driver %d\n", devnum); av_log(s, AV_LOG_INFO, " %s\n", driver_name); av_log(s, AV_LOG_INFO, " %s\n", driver_ver); } } return AVERROR(EIO); } ctx->hwnd = capCreateCaptureWindow(NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, 0); if(!ctx->hwnd) { av_log(s, AV_LOG_ERROR, "Could not create capture window.\n"); return AVERROR(EIO); } /* If atoi fails, devnum==0 and the default device is used */ devnum = atoi(s->filename); ret = SendMessage(ctx->hwnd, WM_CAP_DRIVER_CONNECT, devnum, 0); if(!ret) { av_log(s, AV_LOG_ERROR, "Could not connect to device.\n"); DestroyWindow(ctx->hwnd); return AVERROR(ENODEV); } SendMessage(ctx->hwnd, WM_CAP_SET_OVERLAY, 0, 0); SendMessage(ctx->hwnd, WM_CAP_SET_PREVIEW, 0, 0); ret = SendMessage(ctx->hwnd, WM_CAP_SET_CALLBACK_VIDEOSTREAM, 0, (LPARAM) videostream_cb); if(!ret) { av_log(s, AV_LOG_ERROR, "Could not set video stream callback.\n"); goto fail_io; } SetWindowLongPtr(ctx->hwnd, GWLP_USERDATA, (LONG_PTR) s); st = avformat_new_stream(s, NULL); if(!st) { vfw_read_close(s); return AVERROR(ENOMEM); } /* Set video format */ bisize = SendMessage(ctx->hwnd, WM_CAP_GET_VIDEOFORMAT, 0, 0); if(!bisize) goto fail_io; bi = av_malloc(bisize); if(!bi) { vfw_read_close(s); return AVERROR(ENOMEM); } ret = SendMessage(ctx->hwnd, WM_CAP_GET_VIDEOFORMAT, bisize, (LPARAM) bi); if(!ret) goto fail_bi; dump_bih(s, &bi->bmiHeader); if (ctx->video_size) { ret = av_parse_video_size(&bi->bmiHeader.biWidth, &bi->bmiHeader.biHeight, ctx->video_size); if (ret < 0) { av_log(s, AV_LOG_ERROR, "Couldn't parse video size.\n"); goto fail_bi; } } if (0) { /* For testing yet unsupported compressions * Copy these values from user-supplied verbose information */ bi->bmiHeader.biWidth = 320; bi->bmiHeader.biHeight = 240; bi->bmiHeader.biPlanes = 1; bi->bmiHeader.biBitCount = 12; bi->bmiHeader.biCompression = MKTAG('I','4','2','0'); bi->bmiHeader.biSizeImage = 115200; dump_bih(s, &bi->bmiHeader); } ret = SendMessage(ctx->hwnd, WM_CAP_SET_VIDEOFORMAT, bisize, (LPARAM) bi); if(!ret) { av_log(s, AV_LOG_ERROR, "Could not set Video Format.\n"); goto fail_bi; } biCompression = bi->bmiHeader.biCompression; biBitCount = bi->bmiHeader.biBitCount; av_free(bi); /* Set sequence setup */ ret = SendMessage(ctx->hwnd, WM_CAP_GET_SEQUENCE_SETUP, sizeof(cparms), (LPARAM) &cparms); if(!ret) goto fail_io; dump_captureparms(s, &cparms); cparms.fYield = 1; // Spawn a background thread cparms.dwRequestMicroSecPerFrame = (framerate_q.den*1000000) / framerate_q.num; cparms.fAbortLeftMouse = 0; cparms.fAbortRightMouse = 0; cparms.fCaptureAudio = 0; cparms.vKeyAbort = 0; ret = SendMessage(ctx->hwnd, WM_CAP_SET_SEQUENCE_SETUP, sizeof(cparms), (LPARAM) &cparms); if(!ret) goto fail_io; st->avg_frame_rate = framerate_q; par = st->codecpar; par->codec_type = AVMEDIA_TYPE_VIDEO; par->width = bi->bmiHeader.biWidth; par->height = bi->bmiHeader.biHeight; par->format = vfw_pixfmt(biCompression, biBitCount); if (par->format == AV_PIX_FMT_NONE) { par->codec_id = vfw_codecid(biCompression); if (par->codec_id == AV_CODEC_ID_NONE) { avpriv_report_missing_feature(s, "This compression type"); vfw_read_close(s); return AVERROR_PATCHWELCOME; } par->bits_per_coded_sample = biBitCount; } else { par->codec_id = AV_CODEC_ID_RAWVIDEO; if(biCompression == BI_RGB) { par->bits_per_coded_sample = biBitCount; par->extradata = av_malloc(9 + AV_INPUT_BUFFER_PADDING_SIZE); if (par->extradata) { par->extradata_size = 9; memcpy(par->extradata, "BottomUp", 9); } } } avpriv_set_pts_info(st, 32, 1, 1000); ctx->mutex = CreateMutex(NULL, 0, NULL); if(!ctx->mutex) { av_log(s, AV_LOG_ERROR, "Could not create Mutex.\n" ); goto fail_io; } ctx->event = CreateEvent(NULL, 1, 0, NULL); if(!ctx->event) { av_log(s, AV_LOG_ERROR, "Could not create Event.\n" ); goto fail_io; } ret = SendMessage(ctx->hwnd, WM_CAP_SEQUENCE_NOFILE, 0, 0); if(!ret) { av_log(s, AV_LOG_ERROR, "Could not start capture sequence.\n" ); goto fail_io; } return 0; fail_bi: av_free(bi); fail_io: vfw_read_close(s); return AVERROR(EIO); }
// return 0 on packet, no more left, 1 on packet, 1 on partial packet static int h264_handle_packet(AVFormatContext *ctx, PayloadContext *data, AVStream *st, AVPacket *pkt, uint32_t *timestamp, const uint8_t *buf, int len, uint16_t seq, int flags) { uint8_t nal; uint8_t type; int result = 0; if (!len) { av_log(ctx, AV_LOG_ERROR, "Empty H.264 RTP packet\n"); return AVERROR_INVALIDDATA; } nal = buf[0]; type = nal & 0x1f; /* Simplify the case (these are all the NAL types used internally by * the H.264 codec). */ if (type >= 1 && type <= 23) type = 1; switch (type) { case 0: // undefined, but pass them through case 1: if ((result = av_new_packet(pkt, len + sizeof(start_sequence))) < 0) return result; memcpy(pkt->data, start_sequence, sizeof(start_sequence)); memcpy(pkt->data + sizeof(start_sequence), buf, len); COUNT_NAL_TYPE(data, nal); break; case 24: // STAP-A (one packet, multiple nals) // consume the STAP-A NAL buf++; len--; result = ff_h264_handle_aggregated_packet(ctx, data, pkt, buf, len, 0, NAL_COUNTERS, NAL_MASK); break; case 25: // STAP-B case 26: // MTAP-16 case 27: // MTAP-24 case 29: // FU-B avpriv_report_missing_feature(ctx, "RTP H.264 NAL unit type %d", type); result = AVERROR_PATCHWELCOME; break; case 28: // FU-A (fragmented nal) result = h264_handle_packet_fu_a(ctx, data, pkt, buf, len, NAL_COUNTERS, NAL_MASK); break; case 30: // undefined case 31: // undefined default: av_log(ctx, AV_LOG_ERROR, "Undefined type (%d)\n", type); result = AVERROR_INVALIDDATA; break; } pkt->stream_index = st->index; return result; }
static int skeleton_header(AVFormatContext *s, int idx) { struct ogg *ogg = s->priv_data; struct ogg_stream *os = ogg->streams + idx; AVStream *st = s->streams[idx]; uint8_t *buf = os->buf + os->pstart; int version_major, version_minor; int64_t start_num, start_den; uint64_t start_granule; int target_idx, start_time; strcpy(st->codec->codec_name, "skeleton"); st->codec->codec_type = AVMEDIA_TYPE_DATA; if (os->psize < 8) return -1; if (!strncmp(buf, "fishead", 8)) { if (os->psize < 64) return -1; version_major = AV_RL16(buf+8); version_minor = AV_RL16(buf+10); if (version_major != 3) { av_log(s, AV_LOG_WARNING, "Unknown skeleton version %d.%d\n", version_major, version_minor); return -1; } // This is the overall start time. We use it for the start time of // of the skeleton stream since if left unset lavf assumes 0, // which we don't want since skeleton is timeless // FIXME: the real meaning of this field is "start playback at // this time which can be in the middle of a packet start_num = AV_RL64(buf+12); start_den = AV_RL64(buf+20); if (start_den) { int base_den; av_reduce(&start_time, &base_den, start_num, start_den, INT_MAX); avpriv_set_pts_info(st, 64, 1, base_den); os->lastpts = st->start_time = start_time; } } else if (!strncmp(buf, "fisbone", 8)) { if (os->psize < 52) return -1; target_idx = ogg_find_stream(ogg, AV_RL32(buf+12)); start_granule = AV_RL64(buf+36); if (os->start_granule != OGG_NOGRANULE_VALUE) { avpriv_report_missing_feature(s, "Multiple fisbone for the same stream"); return 1; } if (target_idx >= 0 && start_granule != OGG_NOGRANULE_VALUE) { os->start_granule = start_granule; } } return 1; }
static inline int decode_subframe(FLACContext *s, int channel) { int32_t *decoded = s->decoded[channel]; int type, wasted = 0; int bps = s->bps; int i, tmp, ret; if (channel == 0) { if (s->ch_mode == FLAC_CHMODE_RIGHT_SIDE) bps++; } else { if (s->ch_mode == FLAC_CHMODE_LEFT_SIDE || s->ch_mode == FLAC_CHMODE_MID_SIDE) bps++; } if (get_bits1(&s->gb)) { av_log(s->avctx, AV_LOG_ERROR, "invalid subframe padding\n"); return AVERROR_INVALIDDATA; } type = get_bits(&s->gb, 6); if (get_bits1(&s->gb)) { int left = get_bits_left(&s->gb); wasted = 1; if ( left < 0 || (left < bps && !show_bits_long(&s->gb, left)) || !show_bits_long(&s->gb, bps)) { av_log(s->avctx, AV_LOG_ERROR, "Invalid number of wasted bits > available bits (%d) - left=%d\n", bps, left); return AVERROR_INVALIDDATA; } while (!get_bits1(&s->gb)) wasted++; bps -= wasted; } if (bps > 32) { avpriv_report_missing_feature(s->avctx, "Decorrelated bit depth > 32"); return AVERROR_PATCHWELCOME; } //FIXME use av_log2 for types if (type == 0) { tmp = get_sbits_long(&s->gb, bps); for (i = 0; i < s->blocksize; i++) decoded[i] = tmp; } else if (type == 1) { for (i = 0; i < s->blocksize; i++) decoded[i] = get_sbits_long(&s->gb, bps); } else if ((type >= 8) && (type <= 12)) { if ((ret = decode_subframe_fixed(s, decoded, type & ~0x8, bps)) < 0) return ret; } else if (type >= 32) { if ((ret = decode_subframe_lpc(s, decoded, (type & ~0x20)+1, bps)) < 0) return ret; } else { av_log(s->avctx, AV_LOG_ERROR, "invalid coding type\n"); return AVERROR_INVALIDDATA; } if (wasted) { int i; for (i = 0; i < s->blocksize; i++) decoded[i] <<= wasted; } return 0; }
static int xwd_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { AVFrame *p = data; const uint8_t *buf = avpkt->data; int i, ret, buf_size = avpkt->size; uint32_t version, header_size, vclass, ncolors; uint32_t xoffset, be, bpp, lsize, rsize; uint32_t pixformat, pixdepth, bunit, bitorder, bpad; uint32_t rgb[3]; uint8_t *ptr; GetByteContext gb; if (buf_size < XWD_HEADER_SIZE) return AVERROR_INVALIDDATA; bytestream2_init(&gb, buf, buf_size); header_size = bytestream2_get_be32u(&gb); version = bytestream2_get_be32u(&gb); if (version != XWD_VERSION) { av_log(avctx, AV_LOG_ERROR, "unsupported version\n"); return AVERROR_INVALIDDATA; } if (buf_size < header_size || header_size < XWD_HEADER_SIZE) { av_log(avctx, AV_LOG_ERROR, "invalid header size\n"); return AVERROR_INVALIDDATA; } pixformat = bytestream2_get_be32u(&gb); pixdepth = bytestream2_get_be32u(&gb); avctx->width = bytestream2_get_be32u(&gb); avctx->height = bytestream2_get_be32u(&gb); xoffset = bytestream2_get_be32u(&gb); be = bytestream2_get_be32u(&gb); bunit = bytestream2_get_be32u(&gb); bitorder = bytestream2_get_be32u(&gb); bpad = bytestream2_get_be32u(&gb); bpp = bytestream2_get_be32u(&gb); lsize = bytestream2_get_be32u(&gb); vclass = bytestream2_get_be32u(&gb); rgb[0] = bytestream2_get_be32u(&gb); rgb[1] = bytestream2_get_be32u(&gb); rgb[2] = bytestream2_get_be32u(&gb); bytestream2_skipu(&gb, 8); ncolors = bytestream2_get_be32u(&gb); bytestream2_skipu(&gb, header_size - (XWD_HEADER_SIZE - 20)); av_log(avctx, AV_LOG_DEBUG, "pixformat %"PRIu32", pixdepth %"PRIu32", bunit %"PRIu32", bitorder %"PRIu32", bpad %"PRIu32"\n", pixformat, pixdepth, bunit, bitorder, bpad); av_log(avctx, AV_LOG_DEBUG, "vclass %"PRIu32", ncolors %"PRIu32", bpp %"PRIu32", be %"PRIu32", lsize %"PRIu32", xoffset %"PRIu32"\n", vclass, ncolors, bpp, be, lsize, xoffset); av_log(avctx, AV_LOG_DEBUG, "red %0"PRIx32", green %0"PRIx32", blue %0"PRIx32"\n", rgb[0], rgb[1], rgb[2]); if (pixformat > XWD_Z_PIXMAP) { av_log(avctx, AV_LOG_ERROR, "invalid pixmap format\n"); return AVERROR_INVALIDDATA; } if (pixdepth == 0 || pixdepth > 32) { av_log(avctx, AV_LOG_ERROR, "invalid pixmap depth\n"); return AVERROR_INVALIDDATA; } if (xoffset) { avpriv_request_sample(avctx, "xoffset %"PRIu32"", xoffset); return AVERROR_PATCHWELCOME; } if (be > 1) { av_log(avctx, AV_LOG_ERROR, "invalid byte order\n"); return AVERROR_INVALIDDATA; } if (bitorder > 1) { av_log(avctx, AV_LOG_ERROR, "invalid bitmap bit order\n"); return AVERROR_INVALIDDATA; } if (bunit != 8 && bunit != 16 && bunit != 32) { av_log(avctx, AV_LOG_ERROR, "invalid bitmap unit\n"); return AVERROR_INVALIDDATA; } if (bpad != 8 && bpad != 16 && bpad != 32) { av_log(avctx, AV_LOG_ERROR, "invalid bitmap scan-line pad\n"); return AVERROR_INVALIDDATA; } if (bpp == 0 || bpp > 32) { av_log(avctx, AV_LOG_ERROR, "invalid bits per pixel\n"); return AVERROR_INVALIDDATA; } if (ncolors > 256) { av_log(avctx, AV_LOG_ERROR, "invalid number of entries in colormap\n"); return AVERROR_INVALIDDATA; } if ((ret = av_image_check_size(avctx->width, avctx->height, 0, NULL)) < 0) return ret; rsize = FFALIGN(avctx->width * bpp, bpad) / 8; if (lsize < rsize) { av_log(avctx, AV_LOG_ERROR, "invalid bytes per scan-line\n"); return AVERROR_INVALIDDATA; } if (bytestream2_get_bytes_left(&gb) < ncolors * XWD_CMAP_SIZE + (uint64_t)avctx->height * lsize) { av_log(avctx, AV_LOG_ERROR, "input buffer too small\n"); return AVERROR_INVALIDDATA; } if (pixformat != XWD_Z_PIXMAP) { avpriv_report_missing_feature(avctx, "Pixmap format %"PRIu32, pixformat); return AVERROR_PATCHWELCOME; } avctx->pix_fmt = AV_PIX_FMT_NONE; switch (vclass) { case XWD_STATIC_GRAY: case XWD_GRAY_SCALE: if (bpp != 1 && bpp != 8) return AVERROR_INVALIDDATA; if (bpp == 1 && pixdepth == 1) { avctx->pix_fmt = AV_PIX_FMT_MONOWHITE; } else if (bpp == 8 && pixdepth == 8) { avctx->pix_fmt = AV_PIX_FMT_GRAY8; } break; case XWD_STATIC_COLOR: case XWD_PSEUDO_COLOR: if (bpp == 8) avctx->pix_fmt = AV_PIX_FMT_PAL8; break; case XWD_TRUE_COLOR: case XWD_DIRECT_COLOR: if (bpp != 16 && bpp != 24 && bpp != 32) return AVERROR_INVALIDDATA; if (bpp == 16 && pixdepth == 15) { if (rgb[0] == 0x7C00 && rgb[1] == 0x3E0 && rgb[2] == 0x1F) avctx->pix_fmt = be ? AV_PIX_FMT_RGB555BE : AV_PIX_FMT_RGB555LE; else if (rgb[0] == 0x1F && rgb[1] == 0x3E0 && rgb[2] == 0x7C00) avctx->pix_fmt = be ? AV_PIX_FMT_BGR555BE : AV_PIX_FMT_BGR555LE; } else if (bpp == 16 && pixdepth == 16) { if (rgb[0] == 0xF800 && rgb[1] == 0x7E0 && rgb[2] == 0x1F) avctx->pix_fmt = be ? AV_PIX_FMT_RGB565BE : AV_PIX_FMT_RGB565LE; else if (rgb[0] == 0x1F && rgb[1] == 0x7E0 && rgb[2] == 0xF800) avctx->pix_fmt = be ? AV_PIX_FMT_BGR565BE : AV_PIX_FMT_BGR565LE; } else if (bpp == 24) { if (rgb[0] == 0xFF0000 && rgb[1] == 0xFF00 && rgb[2] == 0xFF) avctx->pix_fmt = be ? AV_PIX_FMT_RGB24 : AV_PIX_FMT_BGR24; else if (rgb[0] == 0xFF && rgb[1] == 0xFF00 && rgb[2] == 0xFF0000) avctx->pix_fmt = be ? AV_PIX_FMT_BGR24 : AV_PIX_FMT_RGB24; } else if (bpp == 32) { if (rgb[0] == 0xFF0000 && rgb[1] == 0xFF00 && rgb[2] == 0xFF) avctx->pix_fmt = be ? AV_PIX_FMT_ARGB : AV_PIX_FMT_BGRA; else if (rgb[0] == 0xFF && rgb[1] == 0xFF00 && rgb[2] == 0xFF0000) avctx->pix_fmt = be ? AV_PIX_FMT_ABGR : AV_PIX_FMT_RGBA; } bytestream2_skipu(&gb, ncolors * XWD_CMAP_SIZE); break; default: av_log(avctx, AV_LOG_ERROR, "invalid visual class\n"); return AVERROR_INVALIDDATA; } if (avctx->pix_fmt == AV_PIX_FMT_NONE) { avpriv_request_sample(avctx, "Unknown file: bpp %"PRIu32", pixdepth %"PRIu32", vclass %"PRIu32"", bpp, pixdepth, vclass); return AVERROR_PATCHWELCOME; } if ((ret = ff_get_buffer(avctx, p, 0)) < 0) return ret; p->key_frame = 1; p->pict_type = AV_PICTURE_TYPE_I; if (avctx->pix_fmt == AV_PIX_FMT_PAL8) { uint32_t *dst = (uint32_t *)p->data[1]; uint8_t red, green, blue; for (i = 0; i < ncolors; i++) { bytestream2_skipu(&gb, 4); // skip colormap entry number red = bytestream2_get_byteu(&gb); bytestream2_skipu(&gb, 1); green = bytestream2_get_byteu(&gb); bytestream2_skipu(&gb, 1); blue = bytestream2_get_byteu(&gb); bytestream2_skipu(&gb, 3); // skip bitmask flag and padding dst[i] = 0xFFU << 24 | red << 16 | green << 8 | blue; } } ptr = p->data[0]; for (i = 0; i < avctx->height; i++) { bytestream2_get_bufferu(&gb, ptr, rsize); bytestream2_skipu(&gb, lsize - rsize); ptr += p->linesize[0]; } *got_frame = 1; return buf_size; }