static int cuvid_h264_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size) { CUVIDContext *ctx = avctx->internal->hwaccel_priv_data; void *tmp; tmp = av_fast_realloc(ctx->bitstream, &ctx->bitstream_allocated, ctx->bitstream_len + size + 3); if (!tmp) return AVERROR(ENOMEM); ctx->bitstream = tmp; tmp = av_fast_realloc(ctx->slice_offsets, &ctx->slice_offsets_allocated, (ctx->nb_slices + 1) * sizeof(*ctx->slice_offsets)); if (!tmp) return AVERROR(ENOMEM); ctx->slice_offsets = tmp; AV_WB24(ctx->bitstream + ctx->bitstream_len, 1); memcpy(ctx->bitstream + ctx->bitstream_len + 3, buffer, size); ctx->slice_offsets[ctx->nb_slices] = ctx->bitstream_len ; ctx->bitstream_len += size + 3; ctx->nb_slices++; return 0; }
static int nvdec_h264_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size) { NVDECContext *ctx = avctx->internal->hwaccel_priv_data; CUVIDPICPARAMS *pp = &ctx->pic_params; const H264Context *h = avctx->priv_data; const H264SliceContext *sl = &h->slice_ctx[0]; void *tmp; tmp = av_fast_realloc(ctx->bitstream, &ctx->bitstream_allocated, ctx->bitstream_len + size + 3); if (!tmp) return AVERROR(ENOMEM); ctx->bitstream = tmp; tmp = av_fast_realloc(ctx->slice_offsets, &ctx->slice_offsets_allocated, (ctx->nb_slices + 1) * sizeof(*ctx->slice_offsets)); if (!tmp) return AVERROR(ENOMEM); ctx->slice_offsets = tmp; AV_WB24(ctx->bitstream + ctx->bitstream_len, 1); memcpy(ctx->bitstream + ctx->bitstream_len + 3, buffer, size); ctx->slice_offsets[ctx->nb_slices] = ctx->bitstream_len ; ctx->bitstream_len += size + 3; ctx->nb_slices++; if (sl->slice_type != AV_PICTURE_TYPE_I && sl->slice_type != AV_PICTURE_TYPE_SI) pp->intra_pic_flag = 0; return 0; }
/** * combines the (truncated) bitstream to a complete frame * @returns -1 if no complete frame could be created */ int ff_combine_frame(ParseContext *pc, int next, const uint8_t **buf, int *buf_size) { #if 0 if(pc->overread){ printf("overread %d, state:%X next:%d index:%d o_index:%d\n", pc->overread, pc->state, next, pc->index, pc->overread_index); printf("%X %X %X %X\n", (*buf)[0], (*buf)[1],(*buf)[2],(*buf)[3]); } #endif /* Copy overread bytes from last frame into buffer. */ for(; pc->overread>0; pc->overread--){ pc->buffer[pc->index++]= pc->buffer[pc->overread_index++]; } /* flush remaining if EOF */ if(!*buf_size && next == END_NOT_FOUND){ next= 0; } pc->last_index= pc->index; /* copy into buffer end return */ if(next == END_NOT_FOUND){ pc->buffer= av_fast_realloc(pc->buffer, &pc->buffer_size, (*buf_size) + pc->index + FF_INPUT_BUFFER_PADDING_SIZE); memcpy(&pc->buffer[pc->index], *buf, *buf_size); pc->index += *buf_size; return -1; } *buf_size= pc->overread_index= pc->index + next; /* append to buffer */ if(pc->index){ pc->buffer= av_fast_realloc(pc->buffer, &pc->buffer_size, next + pc->index + FF_INPUT_BUFFER_PADDING_SIZE); memcpy(&pc->buffer[pc->index], *buf, next + FF_INPUT_BUFFER_PADDING_SIZE ); pc->index = 0; *buf= pc->buffer; } /* store overread bytes */ for(;next < 0; next++){ pc->state = (pc->state<<8) | pc->buffer[pc->last_index + next]; pc->overread++; } #if 0 if(pc->overread){ printf("overread %d, state:%X next:%d index:%d o_index:%d\n", pc->overread, pc->state, next, pc->index, pc->overread_index); printf("%X %X %X %X\n", (*buf)[0], (*buf)[1],(*buf)[2],(*buf)[3]); } #endif return 0; }
static int vda_h264_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size) { VDAContext *vda = avctx->internal->hwaccel_priv_data; H264Context *h = avctx->priv_data; void *tmp; if (h->is_avc == 1) return 0; tmp = av_fast_realloc(vda->bitstream, &vda->allocated_size, vda->bitstream_size + size + 4); if (!tmp) return AVERROR(ENOMEM); vda->bitstream = tmp; AV_WB32(vda->bitstream + vda->bitstream_size, size); memcpy(vda->bitstream + vda->bitstream_size + 4, buffer, size); vda->bitstream_size += size + 4; return 0; }
/** * Non-destructive fast fifo pointer fetching * Returns a pointer from the specified offset. * If possible the pointer points within the fifo buffer. * Otherwise (if it would cause a wrap around,) a pointer to a user-specified * buffer is used. * The pointer can be NULL. In any case it will be reallocated to hold the size. * If the returned pointer will be used after subsequent calls to flac_fifo_read_wrap * then the subsequent calls should pass in a different wrap_buf so as to not * overwrite the contents of the previous wrap_buf. * This function is based on av_fifo_generic_read, which is why there is a comment * about a memory barrier for SMP. */ static uint8_t* flac_fifo_read_wrap(FLACParseContext *fpc, int offset, int len, uint8_t** wrap_buf, int* allocated_size) { AVFifoBuffer *f = fpc->fifo_buf; uint8_t *start = f->rptr + offset; uint8_t *tmp_buf; if (start >= f->end) start -= f->end - f->buffer; if (f->end - start >= len) return start; tmp_buf = av_fast_realloc(*wrap_buf, allocated_size, len); if (!tmp_buf) { av_log(fpc->avctx, AV_LOG_ERROR, "couldn't reallocate wrap buffer of size %d", len); return NULL; } *wrap_buf = tmp_buf; do { int seg_len = FFMIN(f->end - start, len); memcpy(tmp_buf, start, seg_len); tmp_buf = (uint8_t*)tmp_buf + seg_len; // memory barrier needed for SMP here in theory start += seg_len - (f->end - f->buffer); len -= seg_len; } while (len > 0); return *wrap_buf; }
VASliceParameterBufferBase *ff_vaapi_alloc_slice(struct vaapi_context *vactx, const uint8_t *buffer, uint32_t size) { uint8_t *slice_params; VASliceParameterBufferBase *slice_param; if (!vactx->slice_data) vactx->slice_data = buffer; if (vactx->slice_data + vactx->slice_data_size != buffer) { if (ff_vaapi_commit_slices(vactx) < 0) return NULL; vactx->slice_data = buffer; } slice_params = av_fast_realloc(vactx->slice_params, &vactx->slice_params_alloc, (vactx->slice_count + 1) * vactx->slice_param_size); if (!slice_params) return NULL; vactx->slice_params = slice_params; slice_param = (VASliceParameterBufferBase *)(slice_params + vactx->slice_count * vactx->slice_param_size); slice_param->slice_data_size = size; slice_param->slice_data_offset = vactx->slice_data_size; slice_param->slice_data_flag = VA_SLICE_DATA_FLAG_ALL; vactx->slice_count++; vactx->slice_data_size += size; return slice_param; }
AVPacket *ff_subtitles_queue_insert(FFDemuxSubtitlesQueue *q, const uint8_t *event, int len, int merge) { AVPacket *subs, *sub; if (merge && q->nb_subs > 0) { /* merge with previous event */ int old_len; sub = &q->subs[q->nb_subs - 1]; old_len = sub->size; if (av_grow_packet(sub, len) < 0) return NULL; memcpy(sub->data + old_len, event, len); } else { /* new event */ if (q->nb_subs >= INT_MAX/sizeof(*q->subs) - 1) return NULL; subs = av_fast_realloc(q->subs, &q->allocated_size, (q->nb_subs + 1) * sizeof(*q->subs)); if (!subs) return NULL; q->subs = subs; sub = &subs[q->nb_subs++]; if (av_new_packet(sub, len) < 0) return NULL; sub->flags |= AV_PKT_FLAG_KEY; sub->pts = sub->dts = 0; memcpy(sub->data, event, len); } return sub; }
static int get_stats(AVCodecContext *avctx, int eos) { #ifdef TH_ENCCTL_2PASS_OUT TheoraContext *h = avctx->priv_data; uint8_t *buf; int bytes; bytes = th_encode_ctl(h->t_state, TH_ENCCTL_2PASS_OUT, &buf, sizeof(buf)); if (bytes < 0) { av_log(avctx, AV_LOG_ERROR, "Error getting first pass stats\n"); return -1; } if (!eos) { h->stats = av_fast_realloc(h->stats, &h->stats_size, h->stats_offset + bytes); memcpy(h->stats + h->stats_offset, buf, bytes); h->stats_offset += bytes; } else { int b64_size = AV_BASE64_SIZE(h->stats_offset); // libtheora generates a summary header at the end memcpy(h->stats, buf, bytes); avctx->stats_out = av_malloc(b64_size); av_base64_encode(avctx->stats_out, b64_size, h->stats, h->stats_offset); } return 0; #else av_log(avctx, AV_LOG_ERROR, "libtheora too old to support 2pass\n"); return -1; #endif }
static int mxg_update_cache(AVFormatContext *s, unsigned int cache_size) { MXGContext *mxg = s->priv_data; unsigned int current_pos = mxg->buffer_ptr - mxg->buffer; unsigned int soi_pos; int ret; /* reallocate internal buffer */ if (current_pos > current_pos + cache_size) return AVERROR(ENOMEM); if (mxg->soi_ptr) soi_pos = mxg->soi_ptr - mxg->buffer; mxg->buffer = av_fast_realloc(mxg->buffer, &mxg->buffer_size, current_pos + cache_size + FF_INPUT_BUFFER_PADDING_SIZE); if (!mxg->buffer) return AVERROR(ENOMEM); mxg->buffer_ptr = mxg->buffer + current_pos; if (mxg->soi_ptr) mxg->soi_ptr = mxg->buffer + soi_pos; /* get data */ ret = avio_read(s->pb, mxg->buffer_ptr + mxg->cache_size, cache_size - mxg->cache_size); if (ret < 0) return ret; mxg->cache_size += ret; return ret; }
static int caf_write_packet(AVFormatContext *s, AVPacket *pkt) { CAFContext *caf = s->priv_data; avio_write(s->pb, pkt->data, pkt->size); if (!s->streams[0]->codec->block_align) { void *pkt_sizes = caf->pkt_sizes; int i, alloc_size = caf->size_entries_used + 5; if (alloc_size < 0) { caf->pkt_sizes = NULL; } else { caf->pkt_sizes = av_fast_realloc(caf->pkt_sizes, &caf->size_buffer_size, alloc_size); } if (!caf->pkt_sizes) { av_free(pkt_sizes); return AVERROR(ENOMEM); } for (i = 4; i > 0; i--) { unsigned top = pkt->size >> i * 7; if (top) caf->pkt_sizes[caf->size_entries_used++] = 128 | top; } caf->pkt_sizes[caf->size_entries_used++] = pkt->size & 127; caf->packets++; }
static int vda_h264_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size) { struct vda_context *vda_ctx = avctx->hwaccel_context; void *tmp; if (!vda_ctx->decoder) return -1; tmp = av_fast_realloc(vda_ctx->priv_bitstream, &vda_ctx->priv_allocated_size, vda_ctx->priv_bitstream_size + size + 4); if (!tmp) return AVERROR(ENOMEM); vda_ctx->priv_bitstream = tmp; AV_WB32(vda_ctx->priv_bitstream + vda_ctx->priv_bitstream_size, size); memcpy(vda_ctx->priv_bitstream + vda_ctx->priv_bitstream_size + 4, buffer, size); vda_ctx->priv_bitstream_size += size + 4; return 0; }
void ff_xvba_add_slice_data(struct xvba_render_state *render, const uint8_t *buffer, uint32_t size) { render->buffers = av_fast_realloc( render->buffers, &render->buffers_alllocated, sizeof(struct xvba_bitstream_buffers)*(render->num_slices + 1) ); render->buffers[render->num_slices].buffer = buffer; render->buffers[render->num_slices].size = size; render->num_slices++; }
static int xspf_list_files(ByteIOContext *b, char ***flist_ptr, int *len_ptr) { int i, j, c; unsigned int buflen; char state; char **flist, **flist_tmp; char buf[1024]; char buf_tag[10] = {0}; const char match_tag[] = "<location>"; flist = NULL; state = buflen = i = j = 0; while ((c = url_fgetc(b))) { if (c == EOF) break; if (state == 0) { memmove(buf_tag, buf_tag+1, 9); buf_tag[9] = c; if (!memcmp(buf_tag, match_tag, 10)) state = 1; } else { if (c == '<') { termfn: buf[i++] = 0; flist_tmp = av_fast_realloc(flist, &buflen, sizeof(*flist) * (j+2)); if (!flist_tmp) { av_log(NULL, AV_LOG_ERROR, "av_realloc error in m3u_list_files\n"); av_free(flist); return AVERROR_NOMEM; } else flist = flist_tmp; flist[j] = av_malloc(i); av_strlcpy(flist[j++], buf, i); i = 0; state = 0; buf_tag[sizeof(buf_tag)-1] = c; continue; } else { buf[i++] = c; if (i >= sizeof(buf)-1) goto termfn; } } } *flist_ptr = flist; *len_ptr = j; if (!flist) // no files have been found return AVERROR_EOF; flist[j] = 0; return 0; }
/** * allocation of static arrays - do not use for normal allocation. */ void * av_mallocz_static (unsigned int size) { void *ptr = av_mallocz (size); if (ptr) { array_static = av_fast_realloc (array_static, &allocated_static, sizeof (void *) * (last_static + 1)); array_static[last_static++] = ptr; } return ptr; }
void ff_vdpau_add_data_chunk(uint8_t *data, const uint8_t *buf, int buf_size) { struct vdpau_render_state *render = (struct vdpau_render_state*)data; assert(render); render->bitstream_buffers= av_fast_realloc( render->bitstream_buffers, &render->bitstream_buffers_allocated, sizeof(*render->bitstream_buffers)*(render->bitstream_buffers_used + 1) ); render->bitstream_buffers[render->bitstream_buffers_used].struct_version = VDP_BITSTREAM_BUFFER_VERSION; render->bitstream_buffers[render->bitstream_buffers_used].bitstream = buf; render->bitstream_buffers[render->bitstream_buffers_used].bitstream_bytes = buf_size; render->bitstream_buffers_used++; }
int ff_vdpau_add_buffer(Picture *pic, const uint8_t *buf, uint32_t size) { struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private; VdpBitstreamBuffer *buffers = pic_ctx->bitstream_buffers; buffers = av_fast_realloc(buffers, &pic_ctx->bitstream_buffers_allocated, (pic_ctx->bitstream_buffers_used + 1) * sizeof(*buffers)); if (!buffers) return AVERROR(ENOMEM); pic_ctx->bitstream_buffers = buffers; buffers += pic_ctx->bitstream_buffers_used++; buffers->struct_version = VDP_BITSTREAM_BUFFER_VERSION; buffers->bitstream = buf; buffers->bitstream_bytes = size; return 0; }
void ff_vdpau_add_data_chunk(MpegEncContext *s, const uint8_t *buf, int buf_size) { struct vdpau_render_state *render; render = (struct vdpau_render_state *)s->current_picture_ptr->data[0]; assert(render); render->bitstream_buffers= av_fast_realloc( render->bitstream_buffers, &render->bitstream_buffers_allocated, sizeof(*render->bitstream_buffers)*(render->bitstream_buffers_used + 1) ); render->bitstream_buffers[render->bitstream_buffers_used].struct_version = VDP_BITSTREAM_BUFFER_VERSION; render->bitstream_buffers[render->bitstream_buffers_used].bitstream = buf; render->bitstream_buffers[render->bitstream_buffers_used].bitstream_bytes = buf_size; render->bitstream_buffers_used++; }
int ff_vdpau_add_buffer(AVCodecContext *avctx, const uint8_t *buf, uint32_t size) { AVVDPAUContext *hwctx = avctx->hwaccel_context; VdpBitstreamBuffer *buffers = hwctx->bitstream_buffers; buffers = av_fast_realloc(buffers, &hwctx->bitstream_buffers_allocated, (hwctx->bitstream_buffers_used + 1) * sizeof(*buffers)); if (!buffers) return AVERROR(ENOMEM); hwctx->bitstream_buffers = buffers; buffers += hwctx->bitstream_buffers_used++; buffers->struct_version = VDP_BITSTREAM_BUFFER_VERSION; buffers->bitstream = buf; buffers->bitstream_bytes = size; return 0; }
int ff_nvdec_simple_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size) { NVDECContext *ctx = avctx->internal->hwaccel_priv_data; void *tmp; tmp = av_fast_realloc(ctx->slice_offsets, &ctx->slice_offsets_allocated, (ctx->nb_slices + 1) * sizeof(*ctx->slice_offsets)); if (!tmp) return AVERROR(ENOMEM); ctx->slice_offsets = tmp; if (!ctx->bitstream) ctx->bitstream = (uint8_t*)buffer; ctx->slice_offsets[ctx->nb_slices] = buffer - ctx->bitstream; ctx->bitstream_len += size; ctx->nb_slices++; return 0; }
static int vda_h264_start_frame(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size) { VDAContext *vda = avctx->internal->hwaccel_priv_data; H264Context *h = avctx->priv_data; if (h->is_avc == 1) { void *tmp; vda->bitstream_size = 0; tmp = av_fast_realloc(vda->bitstream, &vda->allocated_size, size); vda->bitstream = tmp; memcpy(vda->bitstream, buffer, size); vda->bitstream_size = size; } else { vda->bitstream_size = 0; } return 0; }
int ff_vaapi_commit_slices(struct vaapi_context *vactx) { VABufferID *slice_buf_ids; VABufferID slice_param_buf_id, slice_data_buf_id; if (vactx->slice_count == 0) return 0; slice_buf_ids = av_fast_realloc(vactx->slice_buf_ids, &vactx->slice_buf_ids_alloc, (vactx->n_slice_buf_ids + 2) * sizeof(slice_buf_ids[0])); if (!slice_buf_ids) return -1; vactx->slice_buf_ids = slice_buf_ids; slice_param_buf_id = 0; if (vaCreateBuffer(vactx->display, vactx->context_id, VASliceParameterBufferType, vactx->slice_param_size, vactx->slice_count, vactx->slice_params, &slice_param_buf_id) != VA_STATUS_SUCCESS) return -1; vactx->slice_count = 0; slice_data_buf_id = 0; if (vaCreateBuffer(vactx->display, vactx->context_id, VASliceDataBufferType, vactx->slice_data_size, 1, (void *)vactx->slice_data, &slice_data_buf_id) != VA_STATUS_SUCCESS) return -1; vactx->slice_data = NULL; vactx->slice_data_size = 0; slice_buf_ids[vactx->n_slice_buf_ids++] = slice_param_buf_id; slice_buf_ids[vactx->n_slice_buf_ids++] = slice_data_buf_id; return 0; }
void ff_VDPAU_h264_add_data_chunk(H264Context *h, const uint8_t *buf, int buf_size) { MpegEncContext * s = &h->s; struct vdpau_render_state * render; render = (struct vdpau_render_state*)s->current_picture_ptr->data[0]; assert(render); if (!render->bitstreamBuffersUsed) VDPAU_h264_set_reference_frames(h); render->bitstreamBuffers= av_fast_realloc( render->bitstreamBuffers, &render->bitstreamBuffersAlloced, sizeof(*render->bitstreamBuffers)*(render->bitstreamBuffersUsed + 1) ); render->bitstreamBuffers[render->bitstreamBuffersUsed].struct_version = VDP_BITSTREAM_BUFFER_VERSION; render->bitstreamBuffers[render->bitstreamBuffersUsed].bitstream = buf; render->bitstreamBuffers[render->bitstreamBuffersUsed].bitstream_bytes = buf_size; render->bitstreamBuffersUsed++; }
static int m3u_list_files(ByteIOContext *s, char ***flist_ptr, int *len_ptr) { char **flist, **flist_tmp; int i, bufsize; flist = NULL; i = bufsize = 0; while (1) { char *q; char linebuf[1024] = {0}; if ((q = url_fgets(s, linebuf, sizeof(linebuf))) == NULL) // EOF break; linebuf[sizeof(linebuf)-1] = 0; // cut off end if buffer overflowed while (*q != 0) { if (*q++ == '#') *(q-1) = 0; } if (*linebuf == 0) // hashed out continue; flist_tmp = av_fast_realloc(flist, &bufsize, i+2); if (!flist_tmp) { av_log(NULL, AV_LOG_ERROR, "av_realloc error in m3u_list_files\n"); av_free(flist); return AVERROR_NOMEM; } else flist = flist_tmp; flist[i] = av_malloc(q-linebuf+1); av_strlcpy(flist[i], linebuf, q-linebuf+1); flist[i++][q-linebuf] = 0; } *flist_ptr = flist; *len_ptr = i; if (!flist) // no files have been found return AVERROR_EOF; flist[i] = 0; return 0; }
static int read_header(AVFormatContext *s, AVFormatParameters *ap) { int i, header_remaining; ASSContext *ass = s->priv_data; ByteIOContext *pb = s->pb; AVStream *st; int allocated[2]={0}; uint8_t *p, **dst[2]={0}; int pos[2]={0}; st = av_new_stream(s, 0); if (!st) return -1; av_set_pts_info(st, 64, 1, 100); st->codec->codec_type = CODEC_TYPE_SUBTITLE; st->codec->codec_id= CODEC_ID_SSA; header_remaining= INT_MAX; dst[0] = &st->codec->extradata; dst[1] = &ass->event_buffer; while(!url_feof(pb)){ uint8_t line[MAX_LINESIZE]; get_line(pb, line, sizeof(line)); if(!memcmp(line, "[Events]", 8)) header_remaining= 2; else if(line[0]=='[') header_remaining= INT_MAX; i= header_remaining==0; if(i && get_pts(line, NULL) == AV_NOPTS_VALUE) continue; p = av_fast_realloc(*(dst[i]), &allocated[i], pos[i]+MAX_LINESIZE); if(!p) goto fail; *(dst[i])= p; memcpy(p + pos[i], line, strlen(line)+1); pos[i] += strlen(line); if(i) ass->event_count++; else { header_remaining--; #if 0 if (!header_remaining) { /* write the header into extrada section */ int len = url_ftell(pb); st->codec->extradata = av_mallocz(len + 1); st->codec->extradata_size = len; url_fseek(pb, 0, SEEK_SET); get_buffer(pb, st->codec->extradata, len); } #endif } } st->codec->extradata_size= pos[0]; if(ass->event_count >= UINT_MAX / sizeof(*ass->event)) goto fail; ass->event= av_malloc(ass->event_count * sizeof(*ass->event)); p= ass->event_buffer; for(i=0; i<ass->event_count; i++){ ass->event[i].text= p; ass->event[i].start_time= get_pts(p, &ass->event[i].end_time); while(*p && *p != '\n') p++; p++; } qsort(ass->event, ass->event_count, sizeof(*ass->event), event_cmp); return 0; fail: read_close(s); return -1; }
static int read_frame(BVID_DemuxContext *vid, AVIOContext *pb, AVPacket *pkt, uint8_t block_type, AVFormatContext *s) { uint8_t * vidbuf_start = NULL; int vidbuf_nbytes = 0; int code; int bytes_copied = 0; int position, duration, npixels; unsigned int vidbuf_capacity; int ret = 0; AVStream *st; if (vid->video_index < 0) { st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); vid->video_index = st->index; if (vid->audio_index < 0) { av_log_ask_for_sample(s, "No audio packet before first video " "packet. Using default video time base.\n"); } avpriv_set_pts_info(st, 64, 185, vid->sample_rate); st->codec->codec_type = AVMEDIA_TYPE_VIDEO; st->codec->codec_id = AV_CODEC_ID_BETHSOFTVID; st->codec->width = vid->width; st->codec->height = vid->height; } st = s->streams[vid->video_index]; npixels = st->codec->width * st->codec->height; vidbuf_start = av_malloc(vidbuf_capacity = BUFFER_PADDING_SIZE); if(!vidbuf_start) return AVERROR(ENOMEM); // save the file position for the packet, include block type position = avio_tell(pb) - 1; vidbuf_start[vidbuf_nbytes++] = block_type; // get the current packet duration duration = vid->bethsoft_global_delay + avio_rl16(pb); // set the y offset if it exists (decoder header data should be in data section) if(block_type == VIDEO_YOFF_P_FRAME){ if (avio_read(pb, &vidbuf_start[vidbuf_nbytes], 2) != 2) { ret = AVERROR(EIO); goto fail; } vidbuf_nbytes += 2; } do{ vidbuf_start = av_fast_realloc(vidbuf_start, &vidbuf_capacity, vidbuf_nbytes + BUFFER_PADDING_SIZE); if(!vidbuf_start) return AVERROR(ENOMEM); code = avio_r8(pb); vidbuf_start[vidbuf_nbytes++] = code; if(code >= 0x80){ // rle sequence if(block_type == VIDEO_I_FRAME) vidbuf_start[vidbuf_nbytes++] = avio_r8(pb); } else if(code){ // plain sequence if (avio_read(pb, &vidbuf_start[vidbuf_nbytes], code) != code) { ret = AVERROR(EIO); goto fail; } vidbuf_nbytes += code; } bytes_copied += code & 0x7F; if(bytes_copied == npixels){ // sometimes no stop character is given, need to keep track of bytes copied // may contain a 0 byte even if read all pixels if(avio_r8(pb)) avio_seek(pb, -1, SEEK_CUR); break; } if (bytes_copied > npixels) { ret = AVERROR_INVALIDDATA; goto fail; } } while(code); // copy data into packet if ((ret = av_new_packet(pkt, vidbuf_nbytes)) < 0) goto fail; memcpy(pkt->data, vidbuf_start, vidbuf_nbytes); av_free(vidbuf_start); pkt->pos = position; pkt->stream_index = vid->video_index; pkt->duration = duration; if (block_type == VIDEO_I_FRAME) pkt->flags |= AV_PKT_FLAG_KEY; /* if there is a new palette available, add it to packet side data */ if (vid->palette) { uint8_t *pdata = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, BVID_PALETTE_SIZE); memcpy(pdata, vid->palette, BVID_PALETTE_SIZE); av_freep(&vid->palette); } vid->nframes--; // used to check if all the frames were read return 0; fail: av_free(vidbuf_start); return ret; }
static int read_frame(BVID_DemuxContext *vid, ByteIOContext *pb, AVPacket *pkt, uint8_t block_type, AVFormatContext *s, int npixels) { uint8_t * vidbuf_start = NULL; int vidbuf_nbytes = 0; int code; int bytes_copied = 0; int position; unsigned int vidbuf_capacity; vidbuf_start = av_malloc(vidbuf_capacity = BUFFER_PADDING_SIZE); if(!vidbuf_start) return AVERROR(ENOMEM); // save the file position for the packet, include block type position = url_ftell(pb) - 1; vidbuf_start[vidbuf_nbytes++] = block_type; // get the video delay (next int16), and set the presentation time vid->video_pts += vid->bethsoft_global_delay + get_le16(pb); // set the y offset if it exists (decoder header data should be in data section) if(block_type == VIDEO_YOFF_P_FRAME) { if(get_buffer(pb, &vidbuf_start[vidbuf_nbytes], 2) != 2) goto fail; vidbuf_nbytes += 2; } do { vidbuf_start = av_fast_realloc(vidbuf_start, &vidbuf_capacity, vidbuf_nbytes + BUFFER_PADDING_SIZE); if(!vidbuf_start) return AVERROR(ENOMEM); code = get_byte(pb); vidbuf_start[vidbuf_nbytes++] = code; if(code >= 0x80) { // rle sequence if(block_type == VIDEO_I_FRAME) vidbuf_start[vidbuf_nbytes++] = get_byte(pb); } else if(code) { // plain sequence if(get_buffer(pb, &vidbuf_start[vidbuf_nbytes], code) != code) goto fail; vidbuf_nbytes += code; } bytes_copied += code & 0x7F; if(bytes_copied == npixels) { // sometimes no stop character is given, need to keep track of bytes copied // may contain a 0 byte even if read all pixels if(get_byte(pb)) url_fseek(pb, -1, SEEK_CUR); break; } if(bytes_copied > npixels) goto fail; } while(code); // copy data into packet if(av_new_packet(pkt, vidbuf_nbytes) < 0) goto fail; memcpy(pkt->data, vidbuf_start, vidbuf_nbytes); av_free(vidbuf_start); pkt->pos = position; pkt->stream_index = 0; // use the video decoder, which was initialized as the first stream pkt->pts = vid->video_pts; vid->nframes--; // used to check if all the frames were read return vidbuf_nbytes; fail: av_free(vidbuf_start); return -1; }
static int read_header(AVFormatContext *s) { int i, len, header_remaining; ASSContext *ass = s->priv_data; AVIOContext *pb = s->pb; AVStream *st; int allocated[2]= {0}; uint8_t *p, **dst[2]= {0}; int pos[2]= {0}; st = avformat_new_stream(s, NULL); if (!st) return -1; avpriv_set_pts_info(st, 64, 1, 100); st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE; st->codec->codec_id= AV_CODEC_ID_SSA; header_remaining= INT_MAX; dst[0] = &st->codec->extradata; dst[1] = &ass->event_buffer; while(!pb->eof_reached) { uint8_t line[MAX_LINESIZE]; len = ff_get_line(pb, line, sizeof(line)); if(!memcmp(line, "[Events]", 8)) header_remaining= 2; else if(line[0]=='[') header_remaining= INT_MAX; i= header_remaining==0; if(i && get_pts(line) == AV_NOPTS_VALUE) continue; p = av_fast_realloc(*(dst[i]), &allocated[i], pos[i]+MAX_LINESIZE); if(!p) goto fail; *(dst[i])= p; memcpy(p + pos[i], line, len+1); pos[i] += len; if(i) ass->event_count++; else header_remaining--; } st->codec->extradata_size= pos[0]; if(ass->event_count >= UINT_MAX / sizeof(*ass->event)) goto fail; ass->event= av_malloc(ass->event_count * sizeof(*ass->event)); p= ass->event_buffer; for(i=0; i<ass->event_count; i++) { ass->event[i]= p; while(*p && *p != '\n') p++; p++; } qsort(ass->event, ass->event_count, sizeof(*ass->event), (void*)event_cmp); return 0; fail: read_close(s); return -1; }
int ff_combine_frame(ParseContext *pc, int next, const uint8_t **buf, int *buf_size) { if (pc->overread) { ff_dlog(NULL, "overread %d, state:%X next:%d index:%d o_index:%d\n", pc->overread, pc->state, next, pc->index, pc->overread_index); ff_dlog(NULL, "%X %X %X %X\n", (*buf)[0], (*buf)[1], (*buf)[2], (*buf)[3]); } /* Copy overread bytes from last frame into buffer. */ for (; pc->overread > 0; pc->overread--) pc->buffer[pc->index++] = pc->buffer[pc->overread_index++]; /* flush remaining if EOF */ if (!*buf_size && next == END_NOT_FOUND) next = 0; pc->last_index = pc->index; /* copy into buffer end return */ if (next == END_NOT_FOUND) { void *new_buffer = av_fast_realloc(pc->buffer, &pc->buffer_size, *buf_size + pc->index + AV_INPUT_BUFFER_PADDING_SIZE); if (!new_buffer) { av_log(NULL, AV_LOG_ERROR, "Failed to reallocate parser buffer to %d\n", *buf_size + pc->index + AV_INPUT_BUFFER_PADDING_SIZE); pc->index = 0; return AVERROR(ENOMEM); } pc->buffer = new_buffer; memcpy(&pc->buffer[pc->index], *buf, *buf_size); pc->index += *buf_size; return -1; } *buf_size = pc->overread_index = pc->index + next; /* append to buffer */ if (pc->index) { void *new_buffer = av_fast_realloc(pc->buffer, &pc->buffer_size, next + pc->index + AV_INPUT_BUFFER_PADDING_SIZE); if (!new_buffer) { av_log(NULL, AV_LOG_ERROR, "Failed to reallocate parser buffer to %d\n", next + pc->index + AV_INPUT_BUFFER_PADDING_SIZE); pc->overread_index = pc->index = 0; return AVERROR(ENOMEM); } pc->buffer = new_buffer; if (next > -AV_INPUT_BUFFER_PADDING_SIZE) memcpy(&pc->buffer[pc->index], *buf, next + AV_INPUT_BUFFER_PADDING_SIZE); pc->index = 0; *buf = pc->buffer; } /* store overread bytes */ for (; next < 0; next++) { pc->state = pc->state << 8 | pc->buffer[pc->last_index + next]; pc->state64 = pc->state64 << 8 | pc->buffer[pc->last_index + next]; pc->overread++; } if (pc->overread) { ff_dlog(NULL, "overread %d, state:%X next:%d index:%d o_index:%d\n", pc->overread, pc->state, next, pc->index, pc->overread_index); ff_dlog(NULL, "%X %X %X %X\n", (*buf)[0], (*buf)[1], (*buf)[2], (*buf)[3]); } return 0; }
static int dirac_combine_frame(AVCodecParserContext *s, AVCodecContext *avctx, int next, const uint8_t **buf, int *buf_size) { int parse_timing_info = (s->pts == AV_NOPTS_VALUE && s->dts == AV_NOPTS_VALUE); DiracParseContext *pc = s->priv_data; if (pc->overread_index) { memcpy(pc->buffer, pc->buffer + pc->overread_index, pc->index - pc->overread_index); pc->index -= pc->overread_index; pc->overread_index = 0; if (*buf_size == 0 && pc->buffer[4] == 0x10) { *buf = pc->buffer; *buf_size = pc->index; return 0; } } if ( next == -1) { /* Found a possible frame start but not a frame end */ void *new_buffer = av_fast_realloc(pc->buffer, &pc->buffer_size, pc->index + (*buf_size - pc->sync_offset)); pc->buffer = new_buffer; memcpy(pc->buffer+pc->index, (*buf + pc->sync_offset), *buf_size - pc->sync_offset); pc->index += *buf_size - pc->sync_offset; return -1; } else { /* Found a possible frame start and a possible frame end */ DiracParseUnit pu1, pu; void *new_buffer = av_fast_realloc(pc->buffer, &pc->buffer_size, pc->index + next); pc->buffer = new_buffer; memcpy(pc->buffer + pc->index, *buf, next); pc->index += next; /* Need to check if we have a valid Parse Unit. We can't go by the * sync pattern 'BBCD' alone because arithmetic coding of the residual * and motion data can cause the pattern triggering a false start of * frame. So check if the previous parse offset of the next parse unit * is equal to the next parse offset of the current parse unit then * we can be pretty sure that we have a valid parse unit */ if (!unpack_parse_unit(&pu1, pc, pc->index - 13) || !unpack_parse_unit(&pu, pc, pc->index - 13 - pu1.prev_pu_offset) || pu.next_pu_offset != pu1.prev_pu_offset) { pc->index -= 9; *buf_size = next-9; pc->header_bytes_needed = 9; return -1; } /* All non-frame data must be accompanied by frame data. This is to * ensure that pts is set correctly. So if the current parse unit is * not frame data, wait for frame data to come along */ pc->dirac_unit = pc->buffer + pc->index - 13 - pu1.prev_pu_offset - pc->dirac_unit_size; pc->dirac_unit_size += pu.next_pu_offset; if ((pu.pu_type&0x08) != 0x08) { pc->header_bytes_needed = 9; *buf_size = next; return -1; } /* Get the picture number to set the pts and dts*/ if (parse_timing_info) { uint8_t *cur_pu = pc->buffer + pc->index - 13 - pu1.prev_pu_offset; int pts = AV_RB32(cur_pu + 13); if (s->last_pts == 0 && s->last_dts == 0) s->dts = pts - 1; else s->dts = s->last_dts+1; s->pts = pts; if (!avctx->has_b_frames && (cur_pu[4] & 0x03)) avctx->has_b_frames = 1; } if (avctx->has_b_frames && s->pts == s->dts) s->pict_type = FF_B_TYPE; /* Finally have a complete Dirac data unit */ *buf = pc->dirac_unit; *buf_size = pc->dirac_unit_size; pc->dirac_unit_size = 0; pc->overread_index = pc->index-13; pc->header_bytes_needed = 9; } return next; }
int ff_mms_asf_header_parser(MMSContext *mms) { uint8_t *p = mms->asf_header; uint8_t *end; int flags, stream_id; mms->stream_num = 0; if (mms->asf_header_size < sizeof(ff_asf_guid) * 2 + 22 || memcmp(p, ff_asf_header, sizeof(ff_asf_guid))) { av_log(NULL, AV_LOG_ERROR, "Corrupt stream (invalid ASF header, size=%d)\n", mms->asf_header_size); return AVERROR_INVALIDDATA; } end = mms->asf_header + mms->asf_header_size; p += sizeof(ff_asf_guid) + 14; while(end - p >= sizeof(ff_asf_guid) + 8) { uint64_t chunksize; if (!memcmp(p, ff_asf_data_header, sizeof(ff_asf_guid))) { chunksize = 50; // see Reference [2] section 5.1 } else { chunksize = AV_RL64(p + sizeof(ff_asf_guid)); } if (!chunksize || chunksize > end - p) { av_log(NULL, AV_LOG_ERROR, "Corrupt stream (header chunksize %"PRId64" is invalid)\n", chunksize); return AVERROR_INVALIDDATA; } if (!memcmp(p, ff_asf_file_header, sizeof(ff_asf_guid))) { /* read packet size */ if (end - p > sizeof(ff_asf_guid) * 2 + 68) { mms->asf_packet_len = AV_RL32(p + sizeof(ff_asf_guid) * 2 + 64); mms->file_size = AV_RL64(p + sizeof(ff_asf_guid) * 2 + 8); mms->flags =AV_RL32(p+sizeof(ff_asf_guid)*2+56); if (mms->asf_packet_len <= 0 || mms->asf_packet_len > sizeof(mms->in_buffer)) { av_log(NULL, AV_LOG_ERROR, "Corrupt stream (too large pkt_len %d)\n", mms->asf_packet_len); return AVERROR_INVALIDDATA; } } } else if (!memcmp(p, ff_asf_stream_header, sizeof(ff_asf_guid))) { flags = AV_RL16(p + sizeof(ff_asf_guid)*3 + 24); stream_id = flags & 0x7F; //The second condition is for checking CS_PKT_STREAM_ID_REQUEST packet size, //we can calcuate the packet size by stream_num. //Please see function send_stream_selection_request(). if (mms->stream_num < MMS_MAX_STREAMS && 46 + mms->stream_num * 6 < sizeof(mms->out_buffer)) { mms->streams = av_fast_realloc(mms->streams, &mms->nb_streams_allocated, (mms->stream_num + 1) * sizeof(MMSStream)); mms->streams[mms->stream_num].id = stream_id; mms->stream_num++; } else { av_log(NULL, AV_LOG_ERROR, "Corrupt stream (too many A/V streams)\n"); return AVERROR_INVALIDDATA; } } else if (!memcmp(p, ff_asf_ext_stream_header, sizeof(ff_asf_guid))) { if (end - p >= 88) { int stream_count = AV_RL16(p + 84), ext_len_count = AV_RL16(p + 86); uint64_t skip_bytes = 88; while (stream_count--) { if (end - p < skip_bytes + 4) { av_log(NULL, AV_LOG_ERROR, "Corrupt stream (next stream name length is not in the buffer)\n"); return AVERROR_INVALIDDATA; } skip_bytes += 4 + AV_RL16(p + skip_bytes + 2); } while (ext_len_count--) { if (end - p < skip_bytes + 22) { av_log(NULL, AV_LOG_ERROR, "Corrupt stream (next extension system info length is not in the buffer)\n"); return AVERROR_INVALIDDATA; } skip_bytes += 22 + AV_RL32(p + skip_bytes + 18); } if (end - p < skip_bytes) { av_log(NULL, AV_LOG_ERROR, "Corrupt stream (the last extension system info length is invalid)\n"); return AVERROR_INVALIDDATA; } if (chunksize - skip_bytes > 24) chunksize = skip_bytes; } } else if (!memcmp(p, ff_asf_head1_guid, sizeof(ff_asf_guid))) { chunksize = 46; // see references [2] section 3.4. This should be set 46. } p += chunksize; } return 0; }