int av_bsf_send_packet(AVBSFContext *ctx, AVPacket *pkt) { if (!pkt || (!pkt->data && !pkt->side_data_elems)) { ctx->internal->eof = 1; return 0; } if (ctx->internal->eof) { av_log(ctx, AV_LOG_ERROR, "A non-NULL packet sent after an EOF.\n"); return AVERROR(EINVAL); } if (ctx->internal->buffer_pkt->data || ctx->internal->buffer_pkt->side_data_elems) return AVERROR(EAGAIN); if (pkt->buf) { av_packet_move_ref(ctx->internal->buffer_pkt, pkt); } else { int ret = av_packet_ref(ctx->internal->buffer_pkt, pkt); if (ret < 0) return ret; av_packet_unref(pkt); } return 0; }
static int extract_extradata_filter(AVBSFContext *ctx, AVPacket *out) { ExtractExtradataContext *s = ctx->priv_data; AVPacket *in; uint8_t *extradata = NULL; int extradata_size; int ret = 0; ret = ff_bsf_get_packet(ctx, &in); if (ret < 0) return ret; ret = s->extract(ctx, in, &extradata, &extradata_size); if (ret < 0) goto fail; if (extradata) { ret = av_packet_add_side_data(in, AV_PKT_DATA_NEW_EXTRADATA, extradata, extradata_size); if (ret < 0) { av_freep(&extradata); goto fail; } } av_packet_move_ref(out, in); fail: av_packet_free(&in); return ret; }
static int filter_units_filter(AVBSFContext *bsf, AVPacket *out) { FilterUnitsContext *ctx = bsf->priv_data; CodedBitstreamFragment *frag = &ctx->fragment; AVPacket *in = NULL; int err, i, j; while (1) { err = ff_bsf_get_packet(bsf, &in); if (err < 0) return err; if (ctx->mode == NOOP) { av_packet_move_ref(out, in); av_packet_free(&in); return 0; } err = ff_cbs_read_packet(ctx->cbc, frag, in); if (err < 0) { av_log(bsf, AV_LOG_ERROR, "Failed to read packet.\n"); goto fail; } for (i = 0; i < frag->nb_units; i++) { for (j = 0; j < ctx->nb_types; j++) { if (frag->units[i].type == ctx->type_list[j]) break; } if (ctx->mode == REMOVE ? j < ctx->nb_types : j >= ctx->nb_types) { ff_cbs_delete_unit(ctx->cbc, frag, i); --i; } } if (frag->nb_units > 0) break; // Don't return packets with nothing in them. av_packet_free(&in); ff_cbs_fragment_uninit(ctx->cbc, frag); } err = ff_cbs_write_packet(ctx->cbc, out, frag); if (err < 0) { av_log(bsf, AV_LOG_ERROR, "Failed to write packet.\n"); goto fail; } err = av_packet_copy_props(out, in); if (err < 0) goto fail; fail: ff_cbs_fragment_uninit(ctx->cbc, frag); av_packet_free(&in); return err; }
static int remove_extradata(AVBSFContext *ctx, AVPacket *out) { RemoveExtradataContext *s = ctx->priv_data; AVPacket *in; int ret; ret = ff_bsf_get_packet(ctx, &in); if (ret < 0) return ret; if (s->parser && s->parser->parser->split) { if (s->freq == REMOVE_FREQ_ALL || (s->freq == REMOVE_FREQ_NONKEYFRAME && !(in->flags & AV_PKT_FLAG_KEY)) || (s->freq == REMOVE_FREQ_KEYFRAME && in->flags & AV_PKT_FLAG_KEY)) { int i = s->parser->parser->split(s->avctx, in->data, in->size); in->data += i; in->size -= i; } } av_packet_move_ref(out, in); av_packet_free(&in); return 0; }
int ff_bsf_get_packet_ref(AVBSFContext *ctx, AVPacket *pkt) { AVBSFInternal *in = ctx->internal; if (in->eof) return AVERROR_EOF; if (!ctx->internal->buffer_pkt->data && !ctx->internal->buffer_pkt->side_data_elems) return AVERROR(EAGAIN); av_packet_move_ref(pkt, ctx->internal->buffer_pkt); return 0; }
static int chomp_filter(AVBSFContext *ctx, AVPacket *out) { AVPacket *in; int ret; ret = ff_bsf_get_packet(ctx, &in); if (ret < 0) return ret; while (in->size > 0 && !in->data[in->size - 1]) in->size--; av_packet_move_ref(out, in); av_packet_free(&in); return 0; }
static int trace_headers(AVBSFContext *bsf, AVPacket *out) { TraceHeadersContext *ctx = bsf->priv_data; CodedBitstreamFragment au; AVPacket *in; char tmp[256] = { 0 }; int err; err = ff_bsf_get_packet(bsf, &in); if (err < 0) return err; if (in->flags & AV_PKT_FLAG_KEY) av_strlcat(tmp, ", key frame", sizeof(tmp)); if (in->flags & AV_PKT_FLAG_CORRUPT) av_strlcat(tmp, ", corrupt", sizeof(tmp)); if (in->pts != AV_NOPTS_VALUE) av_strlcatf(tmp, sizeof(tmp), ", pts %"PRId64, in->pts); else av_strlcat(tmp, ", no pts", sizeof(tmp)); if (in->dts != AV_NOPTS_VALUE) av_strlcatf(tmp, sizeof(tmp), ", dts %"PRId64, in->dts); else av_strlcat(tmp, ", no dts", sizeof(tmp)); if (in->duration > 0) av_strlcatf(tmp, sizeof(tmp), ", duration %"PRId64, in->duration); av_log(bsf, AV_LOG_INFO, "Packet: %d bytes%s.\n", in->size, tmp); err = ff_cbs_read_packet(&ctx->cbc, &au, in); if (err < 0) return err; ff_cbs_fragment_uninit(&ctx->cbc, &au); av_packet_move_ref(out, in); av_packet_free(&in); return 0; }
int av_bsf_send_packet(AVBSFContext *ctx, AVPacket *pkt) { if (!pkt) { ctx->internal->eof = 1; return 0; } av_assert0(pkt->data || pkt->side_data); if (ctx->internal->eof) { av_log(ctx, AV_LOG_ERROR, "A non-NULL packet sent after an EOF.\n"); return AVERROR(EINVAL); } if (ctx->internal->buffer_pkt->data || ctx->internal->buffer_pkt->side_data_elems) return AVERROR(EAGAIN); av_packet_move_ref(ctx->internal->buffer_pkt, pkt); return 0; }
static int dump_extradata(AVBSFContext *ctx, AVPacket *out) { DumpExtradataContext *s = ctx->priv_data; AVPacket *in; int ret = 0; ret = ff_bsf_get_packet(ctx, &in); if (ret < 0) return ret; if (ctx->par_in->extradata && (s->freq == DUMP_FREQ_ALL || (s->freq == DUMP_FREQ_KEYFRAME && in->flags & AV_PKT_FLAG_KEY))) { if (in->size >= INT_MAX - ctx->par_in->extradata_size) { ret = AVERROR(ERANGE); goto fail; } ret = av_new_packet(out, in->size + ctx->par_in->extradata_size); if (ret < 0) goto fail; ret = av_packet_copy_props(out, in); if (ret < 0) { av_packet_unref(out); goto fail; } memcpy(out->data, ctx->par_in->extradata, ctx->par_in->extradata_size); memcpy(out->data + ctx->par_in->extradata_size, in->data, in->size); } else { av_packet_move_ref(out, in); } fail: av_packet_free(&in); return ret; }
static int vp9_raw_reorder_make_output(AVBSFContext *bsf, AVPacket *out, VP9RawReorderFrame *last_frame) { VP9RawReorderContext *ctx = bsf->priv_data; VP9RawReorderFrame *next_output = last_frame, *next_display = last_frame, *frame; int s, err; for (s = 0; s < FRAME_SLOTS; s++) { frame = ctx->slot[s]; if (!frame) continue; if (frame->needs_output && (!next_output || frame->sequence < next_output->sequence)) next_output = frame; if (frame->needs_display && (!next_display || frame->pts < next_display->pts)) next_display = frame; } if (!next_output && !next_display) return AVERROR_EOF; if (!next_display || (next_output && next_output->sequence < next_display->sequence)) frame = next_output; else frame = next_display; if (frame->needs_output && frame->needs_display && next_output == next_display) { av_log(bsf, AV_LOG_DEBUG, "Output and display frame " "%"PRId64" (%"PRId64") in order.\n", frame->sequence, frame->pts); av_packet_move_ref(out, frame->packet); frame->needs_output = frame->needs_display = 0; } else if (frame->needs_output) { if (frame->needs_display) { av_log(bsf, AV_LOG_DEBUG, "Output frame %"PRId64" " "(%"PRId64") for later display.\n", frame->sequence, frame->pts); } else { av_log(bsf, AV_LOG_DEBUG, "Output unshown frame " "%"PRId64" (%"PRId64") to keep order.\n", frame->sequence, frame->pts); } av_packet_move_ref(out, frame->packet); out->pts = out->dts; frame->needs_output = 0; } else { PutBitContext pb; av_assert0(!frame->needs_output && frame->needs_display); if (frame->slots == 0) { av_log(bsf, AV_LOG_ERROR, "Attempting to display frame " "which is no longer available?\n"); frame->needs_display = 0; return AVERROR_INVALIDDATA; } s = ff_ctz(frame->slots); av_assert0(s < FRAME_SLOTS); av_log(bsf, AV_LOG_DEBUG, "Display frame %"PRId64" " "(%"PRId64") from slot %d.\n", frame->sequence, frame->pts, s); err = av_new_packet(out, 2); if (err < 0) return err; init_put_bits(&pb, out->data, 2); // frame_marker put_bits(&pb, 2, 2); // profile_low_bit put_bits(&pb, 1, frame->profile & 1); // profile_high_bit put_bits(&pb, 1, (frame->profile >> 1) & 1); if (frame->profile == 3) { // reserved_zero put_bits(&pb, 1, 0); } // show_existing_frame put_bits(&pb, 1, 1); // frame_to_show_map_idx put_bits(&pb, 3, s); while (put_bits_count(&pb) < 16) put_bits(&pb, 1, 0); flush_put_bits(&pb); out->pts = out->dts = frame->pts; frame->needs_display = 0; } return 0; }
void _ffmpegPostAudioFrame(struct mAVStream* stream, int16_t left, int16_t right) { struct FFmpegEncoder* encoder = (struct FFmpegEncoder*) stream; if (!encoder->context || !encoder->audioCodec) { return; } if (encoder->absf && !left) { // XXX: AVBSF doesn't like silence. Figure out why. left = 1; } encoder->audioBuffer[encoder->currentAudioSample * 2] = left; encoder->audioBuffer[encoder->currentAudioSample * 2 + 1] = right; ++encoder->currentAudioSample; if (encoder->currentAudioSample * 4 < encoder->audioBufferSize) { return; } int channelSize = 2 * av_get_bytes_per_sample(encoder->audio->sample_fmt); encoder->currentAudioSample = 0; #ifdef USE_LIBAVRESAMPLE avresample_convert(encoder->resampleContext, 0, 0, 0, (uint8_t**) &encoder->audioBuffer, 0, encoder->audioBufferSize / 4); if (avresample_available(encoder->resampleContext) < encoder->audioFrame->nb_samples) { return; } #if LIBAVCODEC_VERSION_MAJOR >= 55 av_frame_make_writable(encoder->audioFrame); #endif int samples = avresample_read(encoder->resampleContext, encoder->audioFrame->data, encoder->postaudioBufferSize / channelSize); #else #if LIBAVCODEC_VERSION_MAJOR >= 55 av_frame_make_writable(encoder->audioFrame); #endif if (swr_get_out_samples(encoder->resampleContext, encoder->audioBufferSize / 4) < encoder->audioFrame->nb_samples) { swr_convert(encoder->resampleContext, NULL, 0, (const uint8_t**) &encoder->audioBuffer, encoder->audioBufferSize / 4); return; } int samples = swr_convert(encoder->resampleContext, encoder->audioFrame->data, encoder->postaudioBufferSize / channelSize, (const uint8_t**) &encoder->audioBuffer, encoder->audioBufferSize / 4); #endif encoder->audioFrame->pts = av_rescale_q(encoder->currentAudioFrame, encoder->audio->time_base, encoder->audioStream->time_base); encoder->currentAudioFrame += samples; AVPacket packet; av_init_packet(&packet); packet.data = 0; packet.size = 0; packet.pts = encoder->audioFrame->pts; int gotData; #ifdef FFMPEG_USE_PACKETS avcodec_send_frame(encoder->audio, encoder->audioFrame); gotData = avcodec_receive_packet(encoder->audio, &packet); gotData = (gotData == 0) && packet.size; #else avcodec_encode_audio2(encoder->audio, &packet, encoder->audioFrame, &gotData); #endif if (gotData) { if (encoder->absf) { AVPacket tempPacket; #ifdef FFMPEG_USE_NEW_BSF int success = av_bsf_send_packet(encoder->absf, &packet); if (success >= 0) { success = av_bsf_receive_packet(encoder->absf, &tempPacket); } #else int success = av_bitstream_filter_filter(encoder->absf, encoder->audio, 0, &tempPacket.data, &tempPacket.size, packet.data, packet.size, 0); #endif if (success >= 0) { #if LIBAVUTIL_VERSION_MAJOR >= 53 tempPacket.buf = av_buffer_create(tempPacket.data, tempPacket.size, av_buffer_default_free, 0, 0); #endif #ifdef FFMPEG_USE_PACKET_UNREF av_packet_move_ref(&packet, &tempPacket); #else av_free_packet(&packet); packet = tempPacket; #endif packet.stream_index = encoder->audioStream->index; av_interleaved_write_frame(encoder->context, &packet); } } else { packet.stream_index = encoder->audioStream->index; av_interleaved_write_frame(encoder->context, &packet); } } #ifdef FFMPEG_USE_PACKET_UNREF av_packet_unref(&packet); #else av_free_packet(&packet); #endif }
static int mpeg4_unpack_bframes_filter(AVBSFContext *ctx, AVPacket *out) { UnpackBFramesBSFContext *s = ctx->priv_data; int pos_p = -1, nb_vop = 0, pos_vop2 = -1, ret = 0; AVPacket *in; ret = ff_bsf_get_packet(ctx, &in); if (ret < 0) return ret; scan_buffer(in->data, in->size, &pos_p, &nb_vop, &pos_vop2); av_log(ctx, AV_LOG_DEBUG, "Found %d VOP startcode(s) in this packet.\n", nb_vop); if (pos_vop2 >= 0) { if (s->b_frame_buf) { av_log(ctx, AV_LOG_WARNING, "Missing one N-VOP packet, discarding one B-frame.\n"); av_freep(&s->b_frame_buf); s->b_frame_buf_size = 0; } /* store the packed B-frame in the BSFContext */ s->b_frame_buf_size = in->size - pos_vop2; s->b_frame_buf = create_new_buffer(in->data + pos_vop2, s->b_frame_buf_size); if (!s->b_frame_buf) { s->b_frame_buf_size = 0; av_packet_free(&in); return AVERROR(ENOMEM); } } if (nb_vop > 2) { av_log(ctx, AV_LOG_WARNING, "Found %d VOP headers in one packet, only unpacking one.\n", nb_vop); } if (nb_vop == 1 && s->b_frame_buf) { /* use frame from BSFContext */ ret = av_packet_copy_props(out, in); if (ret < 0) { av_packet_free(&in); return ret; } ret = av_packet_from_data(out, s->b_frame_buf, s->b_frame_buf_size); if (ret < 0) { av_packet_free(&in); return ret; } if (in->size <= MAX_NVOP_SIZE) { /* N-VOP */ av_log(ctx, AV_LOG_DEBUG, "Skipping N-VOP.\n"); s->b_frame_buf = NULL; s->b_frame_buf_size = 0; } else { /* copy packet into BSFContext */ s->b_frame_buf_size = in->size; s->b_frame_buf = create_new_buffer(in->data, in->size); if (!s->b_frame_buf) { s->b_frame_buf_size = 0; av_packet_unref(out); av_packet_free(&in); return AVERROR(ENOMEM); } } } else if (nb_vop >= 2) { /* use first frame of the packet */ av_packet_move_ref(out, in); out->size = pos_vop2; } else if (pos_p >= 0) { av_log(ctx, AV_LOG_DEBUG, "Updating DivX userdata (remove trailing 'p').\n"); av_packet_move_ref(out, in); /* remove 'p' (packed) from the end of the (DivX) userdata string */ out->data[pos_p] = '\0'; } else { /* copy packet */ av_packet_move_ref(out, in); } av_packet_free(&in); return 0; }
static int h264_mp4toannexb_filter(AVBSFContext *ctx, AVPacket *out) { H264BSFContext *s = ctx->priv_data; AVPacket *in; uint8_t unit_type; int32_t nal_size; uint32_t cumul_size = 0; const uint8_t *buf; const uint8_t *buf_end; int buf_size; int ret = 0, i; ret = ff_bsf_get_packet(ctx, &in); if (ret < 0) return ret; /* nothing to filter */ if (!s->extradata_parsed) { av_packet_move_ref(out, in); av_packet_free(&in); return 0; } buf = in->data; buf_size = in->size; buf_end = in->data + in->size; do { ret= AVERROR(EINVAL); if (buf + s->length_size > buf_end) goto fail; for (nal_size = 0, i = 0; i<s->length_size; i++) nal_size = (nal_size << 8) | buf[i]; buf += s->length_size; unit_type = *buf & 0x1f; if (nal_size > buf_end - buf || nal_size < 0) goto fail; if (unit_type == 7) s->idr_sps_seen = s->new_idr = 1; else if (unit_type == 8) { s->idr_pps_seen = s->new_idr = 1; /* if SPS has not been seen yet, prepend the AVCC one to PPS */ if (!s->idr_sps_seen) { if (s->sps_offset == -1) av_log(ctx, AV_LOG_WARNING, "SPS not present in the stream, nor in AVCC, stream may be unreadable\n"); else { if ((ret = alloc_and_copy(out, ctx->par_out->extradata + s->sps_offset, s->pps_offset != -1 ? s->pps_offset : ctx->par_out->extradata_size - s->sps_offset, buf, nal_size)) < 0) goto fail; s->idr_sps_seen = 1; goto next_nal; } } } /* if this is a new IDR picture following an IDR picture, reset the idr flag. * Just check first_mb_in_slice to be 0 as this is the simplest solution. * This could be checking idr_pic_id instead, but would complexify the parsing. */ if (!s->new_idr && unit_type == 5 && (buf[1] & 0x80)) s->new_idr = 1; /* prepend only to the first type 5 NAL unit of an IDR picture, if no sps/pps are already present */ if (s->new_idr && unit_type == 5 && !s->idr_sps_seen && !s->idr_pps_seen) { if ((ret=alloc_and_copy(out, ctx->par_out->extradata, ctx->par_out->extradata_size, buf, nal_size)) < 0) goto fail; s->new_idr = 0; /* if only SPS has been seen, also insert PPS */ } else if (s->new_idr && unit_type == 5 && s->idr_sps_seen && !s->idr_pps_seen) { if (s->pps_offset == -1) { av_log(ctx, AV_LOG_WARNING, "PPS not present in the stream, nor in AVCC, stream may be unreadable\n"); if ((ret = alloc_and_copy(out, NULL, 0, buf, nal_size)) < 0) goto fail; } else if ((ret = alloc_and_copy(out, ctx->par_out->extradata + s->pps_offset, ctx->par_out->extradata_size - s->pps_offset, buf, nal_size)) < 0) goto fail; } else { if ((ret=alloc_and_copy(out, NULL, 0, buf, nal_size)) < 0) goto fail; if (!s->new_idr && unit_type == 1) { s->new_idr = 1; s->idr_sps_seen = 0; s->idr_pps_seen = 0; } } next_nal: buf += nal_size; cumul_size += nal_size + s->length_size; } while (cumul_size < buf_size); ret = av_packet_copy_props(out, in); if (ret < 0) goto fail; fail: if (ret < 0) av_packet_unref(out); av_packet_free(&in); return ret; }
static av_cold int ffat_create_decoder(AVCodecContext *avctx, AVPacket *pkt) { ATDecodeContext *at = avctx->priv_data; OSStatus status; int i; enum AVSampleFormat sample_fmt = (avctx->bits_per_raw_sample == 32) ? AV_SAMPLE_FMT_S32 : AV_SAMPLE_FMT_S16; AudioStreamBasicDescription in_format = { .mFormatID = ffat_get_format_id(avctx->codec_id, avctx->profile), .mBytesPerPacket = (avctx->codec_id == AV_CODEC_ID_ILBC) ? avctx->block_align : 0, }; AudioStreamBasicDescription out_format = { .mFormatID = kAudioFormatLinearPCM, .mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked, .mFramesPerPacket = 1, .mBitsPerChannel = av_get_bytes_per_sample(sample_fmt) * 8, }; avctx->sample_fmt = sample_fmt; if (ffat_usable_extradata(avctx)) { UInt32 format_size = sizeof(in_format); UInt32 cookie_size; uint8_t *cookie = ffat_get_magic_cookie(avctx, &cookie_size); if (!cookie) return AVERROR(ENOMEM); status = AudioFormatGetProperty(kAudioFormatProperty_FormatInfo, cookie_size, cookie, &format_size, &in_format); if (cookie != at->extradata) av_free(cookie); if (status != 0) { av_log(avctx, AV_LOG_ERROR, "AudioToolbox header-parse error: %i\n", (int)status); return AVERROR_UNKNOWN; } #if CONFIG_MP1_AT_DECODER || CONFIG_MP2_AT_DECODER || CONFIG_MP3_AT_DECODER } else if (pkt && pkt->size >= 4 && (avctx->codec_id == AV_CODEC_ID_MP1 || avctx->codec_id == AV_CODEC_ID_MP2 || avctx->codec_id == AV_CODEC_ID_MP3)) { enum AVCodecID codec_id; int bit_rate; if (ff_mpa_decode_header(AV_RB32(pkt->data), &avctx->sample_rate, &in_format.mChannelsPerFrame, &avctx->frame_size, &bit_rate, &codec_id) < 0) return AVERROR_INVALIDDATA; avctx->bit_rate = bit_rate; in_format.mSampleRate = avctx->sample_rate; #endif #if CONFIG_AC3_AT_DECODER || CONFIG_EAC3_AT_DECODER } else if (pkt && pkt->size >= 7 && (avctx->codec_id == AV_CODEC_ID_AC3 || avctx->codec_id == AV_CODEC_ID_EAC3)) { AC3HeaderInfo hdr, *phdr = &hdr; GetBitContext gbc; init_get_bits(&gbc, pkt->data, pkt->size); if (avpriv_ac3_parse_header(&gbc, &phdr) < 0) return AVERROR_INVALIDDATA; in_format.mSampleRate = hdr.sample_rate; in_format.mChannelsPerFrame = hdr.channels; avctx->frame_size = hdr.num_blocks * 256; avctx->bit_rate = hdr.bit_rate; #endif } else { in_format.mSampleRate = avctx->sample_rate ? avctx->sample_rate : 44100; in_format.mChannelsPerFrame = avctx->channels ? avctx->channels : 1; } avctx->sample_rate = out_format.mSampleRate = in_format.mSampleRate; avctx->channels = out_format.mChannelsPerFrame = in_format.mChannelsPerFrame; if (avctx->codec_id == AV_CODEC_ID_ADPCM_IMA_QT) in_format.mFramesPerPacket = 64; status = AudioConverterNew(&in_format, &out_format, &at->converter); if (status != 0) { av_log(avctx, AV_LOG_ERROR, "AudioToolbox init error: %i\n", (int)status); return AVERROR_UNKNOWN; } if ((status = ffat_set_extradata(avctx)) < 0) return status; for (i = 0; i < (sizeof(at->channel_map) / sizeof(at->channel_map[0])); i++) at->channel_map[i] = i; ffat_update_ctx(avctx); if(!(at->decoded_data = av_malloc(av_get_bytes_per_sample(avctx->sample_fmt) * avctx->frame_size * avctx->channels))) return AVERROR(ENOMEM); at->last_pts = AV_NOPTS_VALUE; return 0; } static av_cold int ffat_init_decoder(AVCodecContext *avctx) { ATDecodeContext *at = avctx->priv_data; at->extradata = avctx->extradata; at->extradata_size = avctx->extradata_size; if ((avctx->channels && avctx->sample_rate) || ffat_usable_extradata(avctx)) return ffat_create_decoder(avctx, NULL); else return 0; } static OSStatus ffat_decode_callback(AudioConverterRef converter, UInt32 *nb_packets, AudioBufferList *data, AudioStreamPacketDescription **packets, void *inctx) { AVCodecContext *avctx = inctx; ATDecodeContext *at = avctx->priv_data; if (at->eof) { *nb_packets = 0; if (packets) { *packets = &at->pkt_desc; at->pkt_desc.mDataByteSize = 0; } return 0; } av_packet_unref(&at->in_pkt); av_packet_move_ref(&at->in_pkt, &at->new_in_pkt); if (!at->in_pkt.data) { *nb_packets = 0; return 1; } data->mNumberBuffers = 1; data->mBuffers[0].mNumberChannels = 0; data->mBuffers[0].mDataByteSize = at->in_pkt.size; data->mBuffers[0].mData = at->in_pkt.data; *nb_packets = 1; if (packets) { *packets = &at->pkt_desc; at->pkt_desc.mDataByteSize = at->in_pkt.size; } return 0; }
static int h264_mp4toannexb_filter(AVBSFContext *ctx, AVPacket *out) { H264BSFContext *s = ctx->priv_data; AVPacket *in; uint8_t unit_type; int32_t nal_size; uint32_t cumul_size = 0; const uint8_t *buf; const uint8_t *buf_end; int buf_size; int ret = 0; ret = ff_bsf_get_packet(ctx, &in); if (ret < 0) return ret; /* nothing to filter */ if (!s->extradata_parsed) { av_packet_move_ref(out, in); av_packet_free(&in); return 0; } buf = in->data; buf_size = in->size; buf_end = in->data + in->size; do { if (buf + s->length_size > buf_end) goto fail; if (s->length_size == 1) { nal_size = buf[0]; } else if (s->length_size == 2) { nal_size = AV_RB16(buf); } else nal_size = AV_RB32(buf); buf += s->length_size; unit_type = *buf & 0x1f; if (buf + nal_size > buf_end || nal_size < 0) goto fail; /* prepend only to the first type 5 NAL unit of an IDR picture */ if (s->first_idr && unit_type == 5) { if (alloc_and_copy(out, ctx->par_out->extradata, ctx->par_out->extradata_size, buf, nal_size) < 0) goto fail; s->first_idr = 0; } else { if (alloc_and_copy(out, NULL, 0, buf, nal_size) < 0) goto fail; if (!s->first_idr && unit_type == 1) s->first_idr = 1; } buf += nal_size; cumul_size += nal_size + s->length_size; } while (cumul_size < buf_size); ret = av_packet_copy_props(out, in); if (ret < 0) goto fail; fail: if (ret < 0) av_packet_unref(out); av_packet_free(&in); return ret; }