static int asf_write_packet(AVFormatContext *s, AVPacket *pkt) { ASFContext *asf = s->priv_data; AVIOContext *pb = s->pb; ASFStream *stream; AVCodecParameters *par; int64_t packet_st, pts; int start_sec, i; int flags = pkt->flags; uint64_t offset = avio_tell(pb); par = s->streams[pkt->stream_index]->codecpar; stream = &asf->streams[pkt->stream_index]; if (par->codec_type == AVMEDIA_TYPE_AUDIO) flags &= ~AV_PKT_FLAG_KEY; pts = (pkt->pts != AV_NOPTS_VALUE) ? pkt->pts : pkt->dts; assert(pts != AV_NOPTS_VALUE); if (pts > UINT64_MAX - pkt->duration) return AVERROR(ERANGE); asf->duration = FFMAX(asf->duration, pts + pkt->duration); packet_st = asf->nb_packets; put_frame(s, stream, s->streams[pkt->stream_index], pkt->dts, pkt->data, pkt->size, flags); /* check index */ if ((!asf->is_streamed) && (flags & AV_PKT_FLAG_KEY)) { if (pts / 1000LL > INT_MAX) return AVERROR(ERANGE); start_sec = pts / 1000; if (start_sec != asf->last_indexed_pts / 1000) { for (i = asf->nb_index_count; i < start_sec; i++) { if (i >= asf->nb_index_memory_alloc) { int err; asf->nb_index_memory_alloc += ASF_INDEX_BLOCK; if ((err = av_reallocp_array(&asf->index_ptr, asf->nb_index_memory_alloc, sizeof(*asf->index_ptr))) < 0) { asf->nb_index_memory_alloc = 0; return err; } } // store asf->index_ptr[i].packet_number = (uint32_t)packet_st; asf->index_ptr[i].packet_count = (uint16_t)(asf->nb_packets - packet_st); asf->index_ptr[i].send_time = start_sec * INT64_C(10000000); asf->index_ptr[i].offset = offset; asf->maximum_packet = FFMAX(asf->maximum_packet, (uint16_t)(asf->nb_packets - packet_st)); } asf->nb_index_count = start_sec; asf->last_indexed_pts = pts; } } return 0; }
static int update_index(AVFormatContext *s, int start_sec, uint32_t packet_number, uint16_t packet_count) { ASFContext *asf = s->priv_data; if (start_sec > asf->next_start_sec) { int i; if (!asf->next_start_sec) { asf->next_packet_number = packet_number; asf->next_packet_count = packet_count; } if (start_sec > asf->nb_index_memory_alloc) { int err; asf->nb_index_memory_alloc = (start_sec + ASF_INDEX_BLOCK) & ~(ASF_INDEX_BLOCK - 1); if ((err = av_reallocp_array(&asf->index_ptr, asf->nb_index_memory_alloc, sizeof(*asf->index_ptr))) < 0) { asf->nb_index_memory_alloc = 0; return err; } } for (i = asf->next_start_sec; i < start_sec; i++) { asf->index_ptr[i].packet_number = asf->next_packet_number; asf->index_ptr[i].packet_count = asf->next_packet_count; } } asf->maximum_packet = FFMAX(asf->maximum_packet, packet_count); asf->next_packet_number = packet_number; asf->next_packet_count = packet_count; asf->next_start_sec = start_sec; return 0; }
static int gxf_write_map_packet(AVFormatContext *s, int rewrite) { GXFContext *gxf = s->priv_data; AVIOContext *pb = s->pb; int64_t pos = avio_tell(pb); if (!rewrite) { if (!(gxf->map_offsets_nb % 30)) { int err; if ((err = av_reallocp_array(&gxf->map_offsets, gxf->map_offsets_nb + 30, sizeof(*gxf->map_offsets))) < 0) { gxf->map_offsets_nb = 0; av_log(s, AV_LOG_ERROR, "could not realloc map offsets\n"); return err; } } gxf->map_offsets[gxf->map_offsets_nb++] = pos; // do not increment here } gxf_write_packet_header(pb, PKT_MAP); /* preamble */ avio_w8(pb, 0xE0); /* version */ avio_w8(pb, 0xFF); /* reserved */ gxf_write_material_data_section(s); gxf_write_track_description_section(s); return updatePacketSize(pb, pos); }
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags) { AVDictionary *m = *pm; AVDictionaryEntry *tag = av_dict_get(m, key, NULL, flags); char *oldval = NULL; int allocated = !!m; if (!m) m = *pm = av_mallocz(sizeof(*m)); if (!m) return AVERROR(ENOMEM); if (tag) { if (flags & AV_DICT_DONT_OVERWRITE) { if (flags & AV_DICT_DONT_STRDUP_KEY) av_free(key); if (flags & AV_DICT_DONT_STRDUP_VAL) av_free(value); return 0; } if (flags & AV_DICT_APPEND) oldval = tag->value; else av_free(tag->value); av_free(tag->key); *tag = m->elems[--m->count]; } else { int ret = av_reallocp_array(&m->elems, m->count + 1, sizeof(*m->elems)); if (ret < 0) { if (allocated) av_freep(pm); return ret; } } if (value) { if (flags & AV_DICT_DONT_STRDUP_KEY) m->elems[m->count].key = key; else m->elems[m->count].key = av_strdup(key); if (flags & AV_DICT_DONT_STRDUP_VAL) { m->elems[m->count].value = value; } else if (oldval && flags & AV_DICT_APPEND) { int len = strlen(oldval) + strlen(value) + 1; if (!(oldval = av_realloc(oldval, len))) return AVERROR(ENOMEM); av_strlcat(oldval, value, len); m->elems[m->count].value = oldval; } else m->elems[m->count].value = av_strdup(value); m->count++; } if (!m->count) { av_free(m->elems); av_freep(pm); } return 0; }
static int vp56_size_changed(VP56Context *s) { AVCodecContext *avctx = s->avctx; int stride = s->frames[VP56_FRAME_CURRENT]->linesize[0]; int i; s->plane_width[0] = s->plane_width[3] = avctx->coded_width; s->plane_width[1] = s->plane_width[2] = avctx->coded_width/2; s->plane_height[0] = s->plane_height[3] = avctx->coded_height; s->plane_height[1] = s->plane_height[2] = avctx->coded_height/2; for (i=0; i<4; i++) s->stride[i] = s->flip * s->frames[VP56_FRAME_CURRENT]->linesize[i]; s->mb_width = (avctx->coded_width +15) / 16; s->mb_height = (avctx->coded_height+15) / 16; if (s->mb_width > 1000 || s->mb_height > 1000) { avcodec_set_dimensions(avctx, 0, 0); av_log(avctx, AV_LOG_ERROR, "picture too big\n"); return -1; } av_reallocp_array(&s->above_blocks, 4*s->mb_width+6, sizeof(*s->above_blocks)); av_reallocp_array(&s->macroblocks, s->mb_width*s->mb_height, sizeof(*s->macroblocks)); av_free(s->edge_emu_buffer_alloc); s->edge_emu_buffer_alloc = av_malloc(16*stride); s->edge_emu_buffer = s->edge_emu_buffer_alloc; if (!s->above_blocks || !s->macroblocks || !s->edge_emu_buffer_alloc) return AVERROR(ENOMEM); if (s->flip < 0) s->edge_emu_buffer += 15 * stride; if (s->alpha_context) return vp56_size_changed(s->alpha_context); return 0; }
static int gxf_write_packet(AVFormatContext *s, AVPacket *pkt) { GXFContext *gxf = s->priv_data; AVIOContext *pb = s->pb; AVStream *st = s->streams[pkt->stream_index]; int64_t pos = avio_tell(pb); int padding = 0; unsigned packet_start_offset = avio_tell(pb) / 1024; int ret; gxf_write_packet_header(pb, PKT_MEDIA); if (st->codec->codec_id == AV_CODEC_ID_MPEG2VIDEO && pkt->size % 4) /* MPEG-2 frames must be padded */ padding = 4 - pkt->size % 4; else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) padding = GXF_AUDIO_PACKET_SIZE - pkt->size; gxf_write_media_preamble(s, pkt, pkt->size + padding); avio_write(pb, pkt->data, pkt->size); gxf_write_padding(pb, padding); if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { if (!(gxf->flt_entries_nb % 500)) { int err; if ((err = av_reallocp_array(&gxf->flt_entries, gxf->flt_entries_nb + 500, sizeof(*gxf->flt_entries))) < 0) { gxf->flt_entries_nb = 0; gxf->nb_fields = 0; av_log(s, AV_LOG_ERROR, "could not reallocate flt entries\n"); return err; } } gxf->flt_entries[gxf->flt_entries_nb++] = packet_start_offset; gxf->nb_fields += 2; // count fields } updatePacketSize(pb, pos); gxf->packet_count++; if (gxf->packet_count == 100) { if ((ret = gxf_write_map_packet(s, 0)) < 0) return ret; gxf->packet_count = 0; } return 0; }
/** * Update the next thread's AVCodecContext with values set by the user. * * @param dst The destination context. * @param src The source context. * @return 0 on success, negative error code on failure */ static int update_context_from_user(AVCodecContext *dst, AVCodecContext *src) { #define copy_fields(s, e) memcpy(&dst->s, &src->s, (char*)&dst->e - (char*)&dst->s); dst->flags = src->flags; dst->draw_horiz_band= src->draw_horiz_band; dst->get_buffer2 = src->get_buffer2; #if FF_API_GET_BUFFER FF_DISABLE_DEPRECATION_WARNINGS dst->get_buffer = src->get_buffer; dst->release_buffer = src->release_buffer; FF_ENABLE_DEPRECATION_WARNINGS #endif dst->opaque = src->opaque; dst->debug = src->debug; dst->debug_mv = src->debug_mv; dst->slice_flags = src->slice_flags; dst->flags2 = src->flags2; copy_fields(skip_loop_filter, subtitle_header); dst->frame_number = src->frame_number; dst->reordered_opaque = src->reordered_opaque; dst->thread_safe_callbacks = src->thread_safe_callbacks; if (src->slice_count && src->slice_offset) { if (dst->slice_count < src->slice_count) { int err = av_reallocp_array(&dst->slice_offset, src->slice_count, sizeof(*dst->slice_offset)); if (err < 0) return err; } memcpy(dst->slice_offset, src->slice_offset, src->slice_count * sizeof(*dst->slice_offset)); } dst->slice_count = src->slice_count; return 0; #undef copy_fields }
/* FIXME: This is adapted from ff_h264_decode_nal, avoiding duplication * between these functions would be nice. */ int ff_hevc_extract_rbsp(HEVCContext *s, const uint8_t *src, int length, HEVCNAL *nal) { int i, si, di; uint8_t *dst; if (s) s->skipped_bytes = 0; #define STARTCODE_TEST \ if (i + 2 < length && src[i + 1] == 0 && src[i + 2] <= 3) { \ if (src[i + 2] != 3) { \ /* startcode, so we must be past the end */ \ length = i; \ } \ break; \ } #if HAVE_FAST_UNALIGNED #define FIND_FIRST_ZERO \ if (i > 0 && !src[i]) \ i--; \ while (src[i]) \ i++ #if HAVE_FAST_64BIT for (i = 0; i + 1 < length; i += 9) { if (!((~AV_RN64A(src + i) & (AV_RN64A(src + i) - 0x0100010001000101ULL)) & 0x8000800080008080ULL)) continue; FIND_FIRST_ZERO; STARTCODE_TEST; i -= 7; } #else for (i = 0; i + 1 < length; i += 5) { if (!((~AV_RN32A(src + i) & (AV_RN32A(src + i) - 0x01000101U)) & 0x80008080U)) continue; FIND_FIRST_ZERO; STARTCODE_TEST; i -= 3; } #endif /* HAVE_FAST_64BIT */ #else for (i = 0; i + 1 < length; i += 2) { if (src[i]) continue; if (i > 0 && src[i - 1] == 0) i--; STARTCODE_TEST; } #endif /* HAVE_FAST_UNALIGNED */ if (i >= length - 1) { // no escaped 0 nal->data = nal->raw_data = src; nal->size = nal->raw_size = length; return length; } av_fast_malloc(&nal->rbsp_buffer, &nal->rbsp_buffer_size, length + FF_INPUT_BUFFER_PADDING_SIZE); if (!nal->rbsp_buffer) return AVERROR(ENOMEM); dst = nal->rbsp_buffer; memcpy(dst, src, i); si = di = i; while (si + 2 < length) { // remove escapes (very rare 1:2^22) if (src[si + 2] > 3) { dst[di++] = src[si++]; dst[di++] = src[si++]; } else if (src[si] == 0 && src[si + 1] == 0) { if (src[si + 2] == 3) { // escape dst[di++] = 0; dst[di++] = 0; si += 3; if (s) { s->skipped_bytes++; if (s->skipped_bytes_pos_size < s->skipped_bytes) { s->skipped_bytes_pos_size *= 2; av_reallocp_array(&s->skipped_bytes_pos, s->skipped_bytes_pos_size, sizeof(*s->skipped_bytes_pos)); if (!s->skipped_bytes_pos) return AVERROR(ENOMEM); } if (s->skipped_bytes_pos) s->skipped_bytes_pos[s->skipped_bytes-1] = di - 1; } continue; } else // next start code goto nsc; } dst[di++] = src[si++]; } while (si < length) dst[di++] = src[si++]; nsc: memset(dst + di, 0, FF_INPUT_BUFFER_PADDING_SIZE); nal->data = dst; nal->size = di; nal->raw_data = src; nal->raw_size = si; return si; }
static int parse_strk(AVFormatContext *s, FourxmDemuxContext *fourxm, uint8_t *buf, int size, int left) { AVStream *st; int track; /* check that there is enough data */ if (size != strk_SIZE || left < size + 8) return AVERROR_INVALIDDATA; track = AV_RL32(buf + 8); if ((unsigned)track >= UINT_MAX / sizeof(AudioTrack) - 1) { av_log(s, AV_LOG_ERROR, "current_track too large\n"); return AVERROR_INVALIDDATA; } if (track + 1 > fourxm->track_count) { if (av_reallocp_array(&fourxm->tracks, track + 1, sizeof(AudioTrack))) return AVERROR(ENOMEM); memset(&fourxm->tracks[fourxm->track_count], 0, sizeof(AudioTrack) * (track + 1 - fourxm->track_count)); fourxm->track_count = track + 1; } fourxm->tracks[track].adpcm = AV_RL32(buf + 12); fourxm->tracks[track].channels = AV_RL32(buf + 36); fourxm->tracks[track].sample_rate = AV_RL32(buf + 40); fourxm->tracks[track].bits = AV_RL32(buf + 44); fourxm->tracks[track].audio_pts = 0; if (fourxm->tracks[track].channels <= 0 || fourxm->tracks[track].sample_rate <= 0 || fourxm->tracks[track].bits < 0) { av_log(s, AV_LOG_ERROR, "audio header invalid\n"); return AVERROR_INVALIDDATA; } if (!fourxm->tracks[track].adpcm && fourxm->tracks[track].bits<8) { av_log(s, AV_LOG_ERROR, "bits unspecified for non ADPCM\n"); return AVERROR_INVALIDDATA; } /* allocate a new AVStream */ st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); st->id = track; avpriv_set_pts_info(st, 60, 1, fourxm->tracks[track].sample_rate); fourxm->tracks[track].stream_index = st->index; st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_tag = 0; st->codec->channels = fourxm->tracks[track].channels; st->codec->sample_rate = fourxm->tracks[track].sample_rate; st->codec->bits_per_coded_sample = fourxm->tracks[track].bits; st->codec->bit_rate = st->codec->channels * st->codec->sample_rate * st->codec->bits_per_coded_sample; st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample; if (fourxm->tracks[track].adpcm){ st->codec->codec_id = AV_CODEC_ID_ADPCM_4XM; } else if (st->codec->bits_per_coded_sample == 8) { st->codec->codec_id = AV_CODEC_ID_PCM_U8; } else st->codec->codec_id = AV_CODEC_ID_PCM_S16LE; return 0; }