1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * Copyright (c) 2002 Mark Hills <mark@pogo.org.uk> 3cabdff1aSopenharmony_ci * 4cabdff1aSopenharmony_ci * This file is part of FFmpeg. 5cabdff1aSopenharmony_ci * 6cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 7cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 8cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 9cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 10cabdff1aSopenharmony_ci * 11cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 12cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 13cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14cabdff1aSopenharmony_ci * Lesser General Public License for more details. 15cabdff1aSopenharmony_ci * 16cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 17cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 18cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19cabdff1aSopenharmony_ci */ 20cabdff1aSopenharmony_ci 21cabdff1aSopenharmony_ci#include <vorbis/vorbisenc.h> 22cabdff1aSopenharmony_ci 23cabdff1aSopenharmony_ci#include "libavutil/avassert.h" 24cabdff1aSopenharmony_ci#include "libavutil/channel_layout.h" 25cabdff1aSopenharmony_ci#include "libavutil/fifo.h" 26cabdff1aSopenharmony_ci#include "libavutil/opt.h" 27cabdff1aSopenharmony_ci#include "avcodec.h" 28cabdff1aSopenharmony_ci#include "audio_frame_queue.h" 29cabdff1aSopenharmony_ci#include "codec_internal.h" 30cabdff1aSopenharmony_ci#include "encode.h" 31cabdff1aSopenharmony_ci#include "internal.h" 32cabdff1aSopenharmony_ci#include "version.h" 33cabdff1aSopenharmony_ci#include "vorbis.h" 34cabdff1aSopenharmony_ci#include "vorbis_parser.h" 35cabdff1aSopenharmony_ci 36cabdff1aSopenharmony_ci 37cabdff1aSopenharmony_ci/* Number of samples the user should send in each call. 38cabdff1aSopenharmony_ci * This value is used because it is the LCD of all possible frame sizes, so 39cabdff1aSopenharmony_ci * an output packet will always start at the same point as one of the input 40cabdff1aSopenharmony_ci * packets. 41cabdff1aSopenharmony_ci */ 42cabdff1aSopenharmony_ci#define LIBVORBIS_FRAME_SIZE 64 43cabdff1aSopenharmony_ci 44cabdff1aSopenharmony_ci#define BUFFER_SIZE (1024 * 64) 45cabdff1aSopenharmony_ci 46cabdff1aSopenharmony_citypedef struct LibvorbisEncContext { 47cabdff1aSopenharmony_ci AVClass *av_class; /**< class for AVOptions */ 48cabdff1aSopenharmony_ci vorbis_info vi; /**< vorbis_info used during init */ 49cabdff1aSopenharmony_ci vorbis_dsp_state vd; /**< DSP state used for analysis */ 50cabdff1aSopenharmony_ci vorbis_block vb; /**< vorbis_block used for analysis */ 51cabdff1aSopenharmony_ci AVFifo *pkt_fifo; /**< output packet buffer */ 52cabdff1aSopenharmony_ci int eof; /**< end-of-file flag */ 53cabdff1aSopenharmony_ci int dsp_initialized; /**< vd has been initialized */ 54cabdff1aSopenharmony_ci vorbis_comment vc; /**< VorbisComment info */ 55cabdff1aSopenharmony_ci double iblock; /**< impulse block bias option */ 56cabdff1aSopenharmony_ci AVVorbisParseContext *vp; /**< parse context to get durations */ 57cabdff1aSopenharmony_ci AudioFrameQueue afq; /**< frame queue for timestamps */ 58cabdff1aSopenharmony_ci} LibvorbisEncContext; 59cabdff1aSopenharmony_ci 60cabdff1aSopenharmony_cistatic const AVOption options[] = { 61cabdff1aSopenharmony_ci { "iblock", "Sets the impulse block bias", offsetof(LibvorbisEncContext, iblock), AV_OPT_TYPE_DOUBLE, { .dbl = 0 }, -15, 0, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM }, 62cabdff1aSopenharmony_ci { NULL } 63cabdff1aSopenharmony_ci}; 64cabdff1aSopenharmony_ci 65cabdff1aSopenharmony_cistatic const FFCodecDefault defaults[] = { 66cabdff1aSopenharmony_ci { "b", "0" }, 67cabdff1aSopenharmony_ci { NULL }, 68cabdff1aSopenharmony_ci}; 69cabdff1aSopenharmony_ci 70cabdff1aSopenharmony_cistatic const AVClass vorbis_class = { 71cabdff1aSopenharmony_ci .class_name = "libvorbis", 72cabdff1aSopenharmony_ci .item_name = av_default_item_name, 73cabdff1aSopenharmony_ci .option = options, 74cabdff1aSopenharmony_ci .version = LIBAVUTIL_VERSION_INT, 75cabdff1aSopenharmony_ci}; 76cabdff1aSopenharmony_ci 77cabdff1aSopenharmony_cistatic const uint8_t vorbis_encoding_channel_layout_offsets[8][8] = { 78cabdff1aSopenharmony_ci { 0 }, 79cabdff1aSopenharmony_ci { 0, 1 }, 80cabdff1aSopenharmony_ci { 0, 2, 1 }, 81cabdff1aSopenharmony_ci { 0, 1, 2, 3 }, 82cabdff1aSopenharmony_ci { 0, 2, 1, 3, 4 }, 83cabdff1aSopenharmony_ci { 0, 2, 1, 4, 5, 3 }, 84cabdff1aSopenharmony_ci { 0, 2, 1, 5, 6, 4, 3 }, 85cabdff1aSopenharmony_ci { 0, 2, 1, 6, 7, 4, 5, 3 }, 86cabdff1aSopenharmony_ci}; 87cabdff1aSopenharmony_ci 88cabdff1aSopenharmony_cistatic int vorbis_error_to_averror(int ov_err) 89cabdff1aSopenharmony_ci{ 90cabdff1aSopenharmony_ci switch (ov_err) { 91cabdff1aSopenharmony_ci case OV_EFAULT: return AVERROR_BUG; 92cabdff1aSopenharmony_ci case OV_EINVAL: return AVERROR(EINVAL); 93cabdff1aSopenharmony_ci case OV_EIMPL: return AVERROR(EINVAL); 94cabdff1aSopenharmony_ci default: return AVERROR_UNKNOWN; 95cabdff1aSopenharmony_ci } 96cabdff1aSopenharmony_ci} 97cabdff1aSopenharmony_ci 98cabdff1aSopenharmony_cistatic av_cold int libvorbis_setup(vorbis_info *vi, AVCodecContext *avctx) 99cabdff1aSopenharmony_ci{ 100cabdff1aSopenharmony_ci LibvorbisEncContext *s = avctx->priv_data; 101cabdff1aSopenharmony_ci int channels = avctx->ch_layout.nb_channels; 102cabdff1aSopenharmony_ci double cfreq; 103cabdff1aSopenharmony_ci int ret; 104cabdff1aSopenharmony_ci 105cabdff1aSopenharmony_ci if (avctx->flags & AV_CODEC_FLAG_QSCALE || !avctx->bit_rate) { 106cabdff1aSopenharmony_ci /* variable bitrate 107cabdff1aSopenharmony_ci * NOTE: we use the oggenc range of -1 to 10 for global_quality for 108cabdff1aSopenharmony_ci * user convenience, but libvorbis uses -0.1 to 1.0. 109cabdff1aSopenharmony_ci */ 110cabdff1aSopenharmony_ci float q = avctx->global_quality / (float)FF_QP2LAMBDA; 111cabdff1aSopenharmony_ci /* default to 3 if the user did not set quality or bitrate */ 112cabdff1aSopenharmony_ci if (!(avctx->flags & AV_CODEC_FLAG_QSCALE)) 113cabdff1aSopenharmony_ci q = 3.0; 114cabdff1aSopenharmony_ci if ((ret = vorbis_encode_setup_vbr(vi, channels, 115cabdff1aSopenharmony_ci avctx->sample_rate, 116cabdff1aSopenharmony_ci q / 10.0))) 117cabdff1aSopenharmony_ci goto error; 118cabdff1aSopenharmony_ci } else { 119cabdff1aSopenharmony_ci int minrate = avctx->rc_min_rate > 0 ? avctx->rc_min_rate : -1; 120cabdff1aSopenharmony_ci int maxrate = avctx->rc_max_rate > 0 ? avctx->rc_max_rate : -1; 121cabdff1aSopenharmony_ci 122cabdff1aSopenharmony_ci /* average bitrate */ 123cabdff1aSopenharmony_ci if ((ret = vorbis_encode_setup_managed(vi, channels, 124cabdff1aSopenharmony_ci avctx->sample_rate, maxrate, 125cabdff1aSopenharmony_ci avctx->bit_rate, minrate))) 126cabdff1aSopenharmony_ci goto error; 127cabdff1aSopenharmony_ci 128cabdff1aSopenharmony_ci /* variable bitrate by estimate, disable slow rate management */ 129cabdff1aSopenharmony_ci if (minrate == -1 && maxrate == -1) 130cabdff1aSopenharmony_ci if ((ret = vorbis_encode_ctl(vi, OV_ECTL_RATEMANAGE2_SET, NULL))) 131cabdff1aSopenharmony_ci goto error; /* should not happen */ 132cabdff1aSopenharmony_ci } 133cabdff1aSopenharmony_ci 134cabdff1aSopenharmony_ci /* cutoff frequency */ 135cabdff1aSopenharmony_ci if (avctx->cutoff > 0) { 136cabdff1aSopenharmony_ci cfreq = avctx->cutoff / 1000.0; 137cabdff1aSopenharmony_ci if ((ret = vorbis_encode_ctl(vi, OV_ECTL_LOWPASS_SET, &cfreq))) 138cabdff1aSopenharmony_ci goto error; /* should not happen */ 139cabdff1aSopenharmony_ci } 140cabdff1aSopenharmony_ci 141cabdff1aSopenharmony_ci /* impulse block bias */ 142cabdff1aSopenharmony_ci if (s->iblock) { 143cabdff1aSopenharmony_ci if ((ret = vorbis_encode_ctl(vi, OV_ECTL_IBLOCK_SET, &s->iblock))) 144cabdff1aSopenharmony_ci goto error; 145cabdff1aSopenharmony_ci } 146cabdff1aSopenharmony_ci 147cabdff1aSopenharmony_ci if ((channels == 3 && 148cabdff1aSopenharmony_ci av_channel_layout_compare(&avctx->ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_SURROUND)) || 149cabdff1aSopenharmony_ci (channels == 4 && 150cabdff1aSopenharmony_ci av_channel_layout_compare(&avctx->ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_2_2) && 151cabdff1aSopenharmony_ci av_channel_layout_compare(&avctx->ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_QUAD)) || 152cabdff1aSopenharmony_ci (channels == 5 && 153cabdff1aSopenharmony_ci av_channel_layout_compare(&avctx->ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_5POINT0) && 154cabdff1aSopenharmony_ci av_channel_layout_compare(&avctx->ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_5POINT0_BACK)) || 155cabdff1aSopenharmony_ci (channels == 6 && 156cabdff1aSopenharmony_ci av_channel_layout_compare(&avctx->ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_5POINT1) && 157cabdff1aSopenharmony_ci av_channel_layout_compare(&avctx->ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_5POINT1_BACK)) || 158cabdff1aSopenharmony_ci (channels == 7 && 159cabdff1aSopenharmony_ci av_channel_layout_compare(&avctx->ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_6POINT1)) || 160cabdff1aSopenharmony_ci (channels == 8 && 161cabdff1aSopenharmony_ci av_channel_layout_compare(&avctx->ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_7POINT1))) { 162cabdff1aSopenharmony_ci if (avctx->ch_layout.order != AV_CHANNEL_ORDER_UNSPEC) { 163cabdff1aSopenharmony_ci char name[32]; 164cabdff1aSopenharmony_ci av_channel_layout_describe(&avctx->ch_layout, name, sizeof(name)); 165cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "%s not supported by Vorbis: " 166cabdff1aSopenharmony_ci "output stream will have incorrect " 167cabdff1aSopenharmony_ci "channel layout.\n", name); 168cabdff1aSopenharmony_ci } else { 169cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_WARNING, "No channel layout specified. The encoder " 170cabdff1aSopenharmony_ci "will use Vorbis channel layout for " 171cabdff1aSopenharmony_ci "%d channels.\n", channels); 172cabdff1aSopenharmony_ci } 173cabdff1aSopenharmony_ci } 174cabdff1aSopenharmony_ci 175cabdff1aSopenharmony_ci if ((ret = vorbis_encode_setup_init(vi))) 176cabdff1aSopenharmony_ci goto error; 177cabdff1aSopenharmony_ci 178cabdff1aSopenharmony_ci return 0; 179cabdff1aSopenharmony_cierror: 180cabdff1aSopenharmony_ci return vorbis_error_to_averror(ret); 181cabdff1aSopenharmony_ci} 182cabdff1aSopenharmony_ci 183cabdff1aSopenharmony_ci/* How many bytes are needed for a buffer of length 'l' */ 184cabdff1aSopenharmony_cistatic int xiph_len(int l) 185cabdff1aSopenharmony_ci{ 186cabdff1aSopenharmony_ci return 1 + l / 255 + l; 187cabdff1aSopenharmony_ci} 188cabdff1aSopenharmony_ci 189cabdff1aSopenharmony_cistatic av_cold int libvorbis_encode_close(AVCodecContext *avctx) 190cabdff1aSopenharmony_ci{ 191cabdff1aSopenharmony_ci LibvorbisEncContext *s = avctx->priv_data; 192cabdff1aSopenharmony_ci 193cabdff1aSopenharmony_ci /* notify vorbisenc this is EOF */ 194cabdff1aSopenharmony_ci if (s->dsp_initialized) 195cabdff1aSopenharmony_ci vorbis_analysis_wrote(&s->vd, 0); 196cabdff1aSopenharmony_ci 197cabdff1aSopenharmony_ci vorbis_block_clear(&s->vb); 198cabdff1aSopenharmony_ci vorbis_dsp_clear(&s->vd); 199cabdff1aSopenharmony_ci vorbis_info_clear(&s->vi); 200cabdff1aSopenharmony_ci 201cabdff1aSopenharmony_ci av_fifo_freep2(&s->pkt_fifo); 202cabdff1aSopenharmony_ci ff_af_queue_close(&s->afq); 203cabdff1aSopenharmony_ci 204cabdff1aSopenharmony_ci av_vorbis_parse_free(&s->vp); 205cabdff1aSopenharmony_ci 206cabdff1aSopenharmony_ci return 0; 207cabdff1aSopenharmony_ci} 208cabdff1aSopenharmony_ci 209cabdff1aSopenharmony_cistatic av_cold int libvorbis_encode_init(AVCodecContext *avctx) 210cabdff1aSopenharmony_ci{ 211cabdff1aSopenharmony_ci LibvorbisEncContext *s = avctx->priv_data; 212cabdff1aSopenharmony_ci ogg_packet header, header_comm, header_code; 213cabdff1aSopenharmony_ci uint8_t *p; 214cabdff1aSopenharmony_ci unsigned int offset; 215cabdff1aSopenharmony_ci int ret; 216cabdff1aSopenharmony_ci 217cabdff1aSopenharmony_ci vorbis_info_init(&s->vi); 218cabdff1aSopenharmony_ci if ((ret = libvorbis_setup(&s->vi, avctx))) { 219cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "encoder setup failed\n"); 220cabdff1aSopenharmony_ci goto error; 221cabdff1aSopenharmony_ci } 222cabdff1aSopenharmony_ci if ((ret = vorbis_analysis_init(&s->vd, &s->vi))) { 223cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "analysis init failed\n"); 224cabdff1aSopenharmony_ci ret = vorbis_error_to_averror(ret); 225cabdff1aSopenharmony_ci goto error; 226cabdff1aSopenharmony_ci } 227cabdff1aSopenharmony_ci s->dsp_initialized = 1; 228cabdff1aSopenharmony_ci if ((ret = vorbis_block_init(&s->vd, &s->vb))) { 229cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "dsp init failed\n"); 230cabdff1aSopenharmony_ci ret = vorbis_error_to_averror(ret); 231cabdff1aSopenharmony_ci goto error; 232cabdff1aSopenharmony_ci } 233cabdff1aSopenharmony_ci 234cabdff1aSopenharmony_ci vorbis_comment_init(&s->vc); 235cabdff1aSopenharmony_ci if (!(avctx->flags & AV_CODEC_FLAG_BITEXACT)) 236cabdff1aSopenharmony_ci vorbis_comment_add_tag(&s->vc, "encoder", LIBAVCODEC_IDENT); 237cabdff1aSopenharmony_ci 238cabdff1aSopenharmony_ci if ((ret = vorbis_analysis_headerout(&s->vd, &s->vc, &header, &header_comm, 239cabdff1aSopenharmony_ci &header_code))) { 240cabdff1aSopenharmony_ci ret = vorbis_error_to_averror(ret); 241cabdff1aSopenharmony_ci goto error; 242cabdff1aSopenharmony_ci } 243cabdff1aSopenharmony_ci 244cabdff1aSopenharmony_ci avctx->extradata_size = 1 + xiph_len(header.bytes) + 245cabdff1aSopenharmony_ci xiph_len(header_comm.bytes) + 246cabdff1aSopenharmony_ci header_code.bytes; 247cabdff1aSopenharmony_ci p = avctx->extradata = av_malloc(avctx->extradata_size + 248cabdff1aSopenharmony_ci AV_INPUT_BUFFER_PADDING_SIZE); 249cabdff1aSopenharmony_ci if (!p) { 250cabdff1aSopenharmony_ci ret = AVERROR(ENOMEM); 251cabdff1aSopenharmony_ci goto error; 252cabdff1aSopenharmony_ci } 253cabdff1aSopenharmony_ci p[0] = 2; 254cabdff1aSopenharmony_ci offset = 1; 255cabdff1aSopenharmony_ci offset += av_xiphlacing(&p[offset], header.bytes); 256cabdff1aSopenharmony_ci offset += av_xiphlacing(&p[offset], header_comm.bytes); 257cabdff1aSopenharmony_ci memcpy(&p[offset], header.packet, header.bytes); 258cabdff1aSopenharmony_ci offset += header.bytes; 259cabdff1aSopenharmony_ci memcpy(&p[offset], header_comm.packet, header_comm.bytes); 260cabdff1aSopenharmony_ci offset += header_comm.bytes; 261cabdff1aSopenharmony_ci memcpy(&p[offset], header_code.packet, header_code.bytes); 262cabdff1aSopenharmony_ci offset += header_code.bytes; 263cabdff1aSopenharmony_ci av_assert0(offset == avctx->extradata_size); 264cabdff1aSopenharmony_ci 265cabdff1aSopenharmony_ci s->vp = av_vorbis_parse_init(avctx->extradata, avctx->extradata_size); 266cabdff1aSopenharmony_ci if (!s->vp) { 267cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "invalid extradata\n"); 268cabdff1aSopenharmony_ci return ret; 269cabdff1aSopenharmony_ci } 270cabdff1aSopenharmony_ci 271cabdff1aSopenharmony_ci vorbis_comment_clear(&s->vc); 272cabdff1aSopenharmony_ci 273cabdff1aSopenharmony_ci avctx->frame_size = LIBVORBIS_FRAME_SIZE; 274cabdff1aSopenharmony_ci ff_af_queue_init(avctx, &s->afq); 275cabdff1aSopenharmony_ci 276cabdff1aSopenharmony_ci s->pkt_fifo = av_fifo_alloc2(BUFFER_SIZE, 1, 0); 277cabdff1aSopenharmony_ci if (!s->pkt_fifo) { 278cabdff1aSopenharmony_ci ret = AVERROR(ENOMEM); 279cabdff1aSopenharmony_ci goto error; 280cabdff1aSopenharmony_ci } 281cabdff1aSopenharmony_ci 282cabdff1aSopenharmony_ci return 0; 283cabdff1aSopenharmony_cierror: 284cabdff1aSopenharmony_ci libvorbis_encode_close(avctx); 285cabdff1aSopenharmony_ci return ret; 286cabdff1aSopenharmony_ci} 287cabdff1aSopenharmony_ci 288cabdff1aSopenharmony_cistatic int libvorbis_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, 289cabdff1aSopenharmony_ci const AVFrame *frame, int *got_packet_ptr) 290cabdff1aSopenharmony_ci{ 291cabdff1aSopenharmony_ci LibvorbisEncContext *s = avctx->priv_data; 292cabdff1aSopenharmony_ci ogg_packet op; 293cabdff1aSopenharmony_ci int ret, duration; 294cabdff1aSopenharmony_ci 295cabdff1aSopenharmony_ci /* send samples to libvorbis */ 296cabdff1aSopenharmony_ci if (frame) { 297cabdff1aSopenharmony_ci const int samples = frame->nb_samples; 298cabdff1aSopenharmony_ci float **buffer; 299cabdff1aSopenharmony_ci int c, channels = s->vi.channels; 300cabdff1aSopenharmony_ci 301cabdff1aSopenharmony_ci buffer = vorbis_analysis_buffer(&s->vd, samples); 302cabdff1aSopenharmony_ci for (c = 0; c < channels; c++) { 303cabdff1aSopenharmony_ci int co = (channels > 8) ? c : 304cabdff1aSopenharmony_ci vorbis_encoding_channel_layout_offsets[channels - 1][c]; 305cabdff1aSopenharmony_ci memcpy(buffer[c], frame->extended_data[co], 306cabdff1aSopenharmony_ci samples * sizeof(*buffer[c])); 307cabdff1aSopenharmony_ci } 308cabdff1aSopenharmony_ci if ((ret = vorbis_analysis_wrote(&s->vd, samples)) < 0) { 309cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "error in vorbis_analysis_wrote()\n"); 310cabdff1aSopenharmony_ci return vorbis_error_to_averror(ret); 311cabdff1aSopenharmony_ci } 312cabdff1aSopenharmony_ci if ((ret = ff_af_queue_add(&s->afq, frame)) < 0) 313cabdff1aSopenharmony_ci return ret; 314cabdff1aSopenharmony_ci } else { 315cabdff1aSopenharmony_ci if (!s->eof && s->afq.frame_alloc) 316cabdff1aSopenharmony_ci if ((ret = vorbis_analysis_wrote(&s->vd, 0)) < 0) { 317cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "error in vorbis_analysis_wrote()\n"); 318cabdff1aSopenharmony_ci return vorbis_error_to_averror(ret); 319cabdff1aSopenharmony_ci } 320cabdff1aSopenharmony_ci s->eof = 1; 321cabdff1aSopenharmony_ci } 322cabdff1aSopenharmony_ci 323cabdff1aSopenharmony_ci /* retrieve available packets from libvorbis */ 324cabdff1aSopenharmony_ci while ((ret = vorbis_analysis_blockout(&s->vd, &s->vb)) == 1) { 325cabdff1aSopenharmony_ci if ((ret = vorbis_analysis(&s->vb, NULL)) < 0) 326cabdff1aSopenharmony_ci break; 327cabdff1aSopenharmony_ci if ((ret = vorbis_bitrate_addblock(&s->vb)) < 0) 328cabdff1aSopenharmony_ci break; 329cabdff1aSopenharmony_ci 330cabdff1aSopenharmony_ci /* add any available packets to the output packet buffer */ 331cabdff1aSopenharmony_ci while ((ret = vorbis_bitrate_flushpacket(&s->vd, &op)) == 1) { 332cabdff1aSopenharmony_ci if (av_fifo_can_write(s->pkt_fifo) < sizeof(ogg_packet) + op.bytes) { 333cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "packet buffer is too small\n"); 334cabdff1aSopenharmony_ci return AVERROR_BUG; 335cabdff1aSopenharmony_ci } 336cabdff1aSopenharmony_ci av_fifo_write(s->pkt_fifo, &op, sizeof(ogg_packet)); 337cabdff1aSopenharmony_ci av_fifo_write(s->pkt_fifo, op.packet, op.bytes); 338cabdff1aSopenharmony_ci } 339cabdff1aSopenharmony_ci if (ret < 0) { 340cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "error getting available packets\n"); 341cabdff1aSopenharmony_ci break; 342cabdff1aSopenharmony_ci } 343cabdff1aSopenharmony_ci } 344cabdff1aSopenharmony_ci if (ret < 0) { 345cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "error getting available packets\n"); 346cabdff1aSopenharmony_ci return vorbis_error_to_averror(ret); 347cabdff1aSopenharmony_ci } 348cabdff1aSopenharmony_ci 349cabdff1aSopenharmony_ci /* Read an available packet if possible */ 350cabdff1aSopenharmony_ci if (av_fifo_read(s->pkt_fifo, &op, sizeof(ogg_packet)) < 0) 351cabdff1aSopenharmony_ci return 0; 352cabdff1aSopenharmony_ci 353cabdff1aSopenharmony_ci if ((ret = ff_get_encode_buffer(avctx, avpkt, op.bytes, 0)) < 0) 354cabdff1aSopenharmony_ci return ret; 355cabdff1aSopenharmony_ci av_fifo_read(s->pkt_fifo, avpkt->data, op.bytes); 356cabdff1aSopenharmony_ci 357cabdff1aSopenharmony_ci avpkt->pts = ff_samples_to_time_base(avctx, op.granulepos); 358cabdff1aSopenharmony_ci 359cabdff1aSopenharmony_ci duration = av_vorbis_parse_frame(s->vp, avpkt->data, avpkt->size); 360cabdff1aSopenharmony_ci if (duration > 0) { 361cabdff1aSopenharmony_ci /* we do not know encoder delay until we get the first packet from 362cabdff1aSopenharmony_ci * libvorbis, so we have to update the AudioFrameQueue counts */ 363cabdff1aSopenharmony_ci if (!avctx->initial_padding && s->afq.frames) { 364cabdff1aSopenharmony_ci avctx->initial_padding = duration; 365cabdff1aSopenharmony_ci av_assert0(!s->afq.remaining_delay); 366cabdff1aSopenharmony_ci s->afq.frames->duration += duration; 367cabdff1aSopenharmony_ci if (s->afq.frames->pts != AV_NOPTS_VALUE) 368cabdff1aSopenharmony_ci s->afq.frames->pts -= duration; 369cabdff1aSopenharmony_ci s->afq.remaining_samples += duration; 370cabdff1aSopenharmony_ci } 371cabdff1aSopenharmony_ci ff_af_queue_remove(&s->afq, duration, &avpkt->pts, &avpkt->duration); 372cabdff1aSopenharmony_ci } 373cabdff1aSopenharmony_ci 374cabdff1aSopenharmony_ci *got_packet_ptr = 1; 375cabdff1aSopenharmony_ci return 0; 376cabdff1aSopenharmony_ci} 377cabdff1aSopenharmony_ci 378cabdff1aSopenharmony_ciconst FFCodec ff_libvorbis_encoder = { 379cabdff1aSopenharmony_ci .p.name = "libvorbis", 380cabdff1aSopenharmony_ci .p.long_name = NULL_IF_CONFIG_SMALL("libvorbis"), 381cabdff1aSopenharmony_ci .p.type = AVMEDIA_TYPE_AUDIO, 382cabdff1aSopenharmony_ci .p.id = AV_CODEC_ID_VORBIS, 383cabdff1aSopenharmony_ci .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY | 384cabdff1aSopenharmony_ci AV_CODEC_CAP_SMALL_LAST_FRAME, 385cabdff1aSopenharmony_ci .priv_data_size = sizeof(LibvorbisEncContext), 386cabdff1aSopenharmony_ci .init = libvorbis_encode_init, 387cabdff1aSopenharmony_ci FF_CODEC_ENCODE_CB(libvorbis_encode_frame), 388cabdff1aSopenharmony_ci .close = libvorbis_encode_close, 389cabdff1aSopenharmony_ci .p.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, 390cabdff1aSopenharmony_ci AV_SAMPLE_FMT_NONE }, 391cabdff1aSopenharmony_ci .p.priv_class = &vorbis_class, 392cabdff1aSopenharmony_ci .defaults = defaults, 393cabdff1aSopenharmony_ci .p.wrapper_name = "libvorbis", 394cabdff1aSopenharmony_ci}; 395