static int encode_audio_frame(AVFormatContext *s, OutputStream *ost, const uint8_t *buf, int buf_size) { AVCodecContext *enc = ost->st->codec; AVFrame *frame = NULL; AVPacket pkt; int ret, got_packet; av_init_packet(&pkt); pkt.data = NULL; pkt.size = 0; if (buf && buf_size) { if (!ost->output_frame) { ost->output_frame = avcodec_alloc_frame(); if (!ost->output_frame) { av_log(NULL, AV_LOG_FATAL, "out-of-memory in encode_audio_frame()\n"); exit_program(1); } } frame = ost->output_frame; if (frame->extended_data != frame->data) av_freep(&frame->extended_data); avcodec_get_frame_defaults(frame); frame->nb_samples = buf_size / (enc->channels * av_get_bytes_per_sample(enc->sample_fmt)); if ((ret = avcodec_fill_audio_frame(frame, enc->channels, enc->sample_fmt, buf, buf_size, 1)) < 0) { av_log(NULL, AV_LOG_FATAL, "Audio encoding failed (avcodec_fill_audio_frame)\n"); exit_program(1); } frame->pts = ost->sync_opts; ost->sync_opts += frame->nb_samples; } got_packet = 0; update_benchmark(NULL); if (avcodec_encode_audio2(enc, &pkt, frame, &got_packet) < 0) { av_log(NULL, AV_LOG_FATAL, "Audio encoding failed (avcodec_encode_audio2)\n"); exit_program(1); } update_benchmark("encode_audio %d.%d", ost->file_index, ost->index); ret = pkt.size; if (got_packet) { if (pkt.pts != AV_NOPTS_VALUE) pkt.pts = av_rescale_q(pkt.pts, enc->time_base, ost->st->time_base); if (pkt.dts != AV_NOPTS_VALUE) { int64_t max = ost->st->cur_dts + !(s->oformat->flags & AVFMT_TS_NONSTRICT); pkt.dts = av_rescale_q(pkt.dts, enc->time_base, ost->st->time_base); if (ost->st->cur_dts && ost->st->cur_dts != AV_NOPTS_VALUE && max > pkt.dts) { av_log(s, max - pkt.dts > 2 ? AV_LOG_WARNING : AV_LOG_DEBUG, "Audio timestamp %"PRId64" < %"PRId64" invalid, cliping\n", pkt.dts, max); pkt.pts = pkt.dts = max; } } if (pkt.duration > 0) pkt.duration = av_rescale_q(pkt.duration, enc->time_base, ost->st->time_base); write_frame(s, &pkt, ost); audio_size += pkt.size; av_free_packet(&pkt); } if (debug_ts) { av_log(NULL, AV_LOG_INFO, "encoder -> type:audio " "pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s\n", av_ts2str(pkt.pts), av_ts2timestr(pkt.pts, &ost->st->time_base), av_ts2str(pkt.dts), av_ts2timestr(pkt.dts, &ost->st->time_base)); } return ret; }