Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ad_ffmpeg.c 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392
  1. /**
  2. Copyright (C) 2011-2013 Robin Gareus <robin@gareus.org>
  3. Copyright (C) 2014-2023 Filipe Coelho <falktx@falktx.com>
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU Lesser Public License as published by
  6. the Free Software Foundation; either version 2.1, or (at your option)
  7. any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU Lesser Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public
  13. License along with this library; if not, write to the Free Software
  14. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  15. */
  16. #include "ad_plugin.h"
  17. #ifdef HAVE_FFMPEG
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <string.h>
  21. #include <unistd.h>
  22. #include <math.h>
  23. #include "ffcompat.h"
  24. #ifndef MIN
  25. #define MIN(a,b) ( ( (a) < (b) )? (a) : (b) )
  26. #endif
  27. typedef struct {
  28. AVFormatContext* formatContext;
  29. AVCodecContext* codecContext;
  30. AVCodec* codec;
  31. AVPacket packet;
  32. int audioStream;
  33. int pkt_len;
  34. uint8_t* pkt_ptr;
  35. int16_t m_tmpBuffer[AVCODEC_MAX_AUDIO_FRAME_SIZE];
  36. int16_t* m_tmpBufferStart;
  37. unsigned long m_tmpBufferLen;
  38. int64_t decoder_clock;
  39. int64_t output_clock;
  40. int64_t seek_frame;
  41. unsigned int samplerate;
  42. unsigned int channels;
  43. int64_t length;
  44. } ffmpeg_audio_decoder;
  45. static int ad_info_ffmpeg(void *sf, struct adinfo *nfo) {
  46. ffmpeg_audio_decoder *priv = (ffmpeg_audio_decoder*) sf;
  47. if (!priv) return -1;
  48. if (nfo) {
  49. nfo->sample_rate = priv->samplerate;
  50. nfo->channels = priv->channels;
  51. nfo->frames = priv->length;
  52. if (nfo->sample_rate==0) return -1;
  53. nfo->length = (nfo->frames * 1000) / nfo->sample_rate;
  54. nfo->bit_rate = priv->formatContext->bit_rate;
  55. nfo->bit_depth = 0;
  56. nfo->meta_data = NULL;
  57. nfo->can_seek = 1;
  58. #ifdef WITH_GTK // XXX replace g_* functions with POSIX equiv
  59. AVDictionaryEntry *tag = NULL;
  60. // Tags in container
  61. while ((tag = av_dict_get(priv->formatContext->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) {
  62. dbg(2, "FTAG: %s=%s", tag->key, tag->value);
  63. char * tmp = g_strdup_printf("%s%s<i>%s</i>:%s", nfo->meta_data?nfo->meta_data:"",nfo->meta_data?"\n":"", tag->key, tag->value);
  64. if (nfo->meta_data) g_free(nfo->meta_data);
  65. nfo->meta_data = tmp;
  66. }
  67. // Tags in stream
  68. tag=NULL;
  69. AVStream *stream = priv->formatContext->streams[priv->audioStream];
  70. while ((tag = av_dict_get(stream->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) {
  71. dbg(2, "STAG: %s=%s", tag->key, tag->value);
  72. char * tmp = g_strdup_printf("%s%s<i>%s</i>:%s", nfo->meta_data?nfo->meta_data:"",nfo->meta_data?"\n":"", tag->key, tag->value);
  73. if (nfo->meta_data) g_free(nfo->meta_data);
  74. nfo->meta_data = tmp;
  75. }
  76. #endif
  77. }
  78. return 0;
  79. }
  80. static void *ad_open_ffmpeg(const char *fn, struct adinfo *nfo) {
  81. ffmpeg_audio_decoder *priv = (ffmpeg_audio_decoder*) calloc(1, sizeof(ffmpeg_audio_decoder));
  82. priv->m_tmpBufferStart=NULL;
  83. priv->m_tmpBufferLen=0;
  84. priv->decoder_clock=priv->output_clock=priv->seek_frame=0;
  85. priv->packet.size=0; priv->packet.data=NULL;
  86. if (avformat_open_input(&priv->formatContext, fn, NULL, NULL) <0) {
  87. dbg(0, "ffmpeg is unable to open file '%s'.", fn);
  88. free(priv); return(NULL);
  89. }
  90. if (avformat_find_stream_info(priv->formatContext, NULL) < 0) {
  91. avformat_close_input(&priv->formatContext);
  92. dbg(0, "av_find_stream_info failed" );
  93. free(priv); return(NULL);
  94. }
  95. priv->audioStream = -1;
  96. unsigned int i;
  97. for (i=0; i<priv->formatContext->nb_streams; i++) {
  98. if (priv->formatContext->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
  99. priv->audioStream = i;
  100. break;
  101. }
  102. }
  103. if (priv->audioStream == -1) {
  104. dbg(0, "No Audio Stream found in file");
  105. avformat_close_input(&priv->formatContext);
  106. free(priv); return(NULL);
  107. }
  108. priv->codecContext = priv->formatContext->streams[priv->audioStream]->codec;
  109. priv->codec = avcodec_find_decoder(priv->codecContext->codec_id);
  110. if (priv->codec == NULL) {
  111. avformat_close_input(&priv->formatContext);
  112. dbg(0, "Codec not supported by ffmpeg");
  113. free(priv); return(NULL);
  114. }
  115. if (avcodec_open2(priv->codecContext, priv->codec, NULL) < 0) {
  116. dbg(0, "avcodec_open failed" );
  117. free(priv); return(NULL);
  118. }
  119. dbg(2, "ffmpeg - audio tics: %i/%i [sec]",priv->formatContext->streams[priv->audioStream]->time_base.num,priv->formatContext->streams[priv->audioStream]->time_base.den);
  120. int64_t len = priv->formatContext->duration - priv->formatContext->start_time;
  121. priv->formatContext->flags|=AVFMT_FLAG_GENPTS;
  122. priv->formatContext->flags|=AVFMT_FLAG_IGNIDX;
  123. priv->samplerate = priv->codecContext->sample_rate;
  124. priv->channels = priv->codecContext->channels ;
  125. priv->length = (int64_t)( len * priv->samplerate / AV_TIME_BASE );
  126. if (ad_info_ffmpeg((void*)priv, nfo)) {
  127. dbg(0, "invalid file info (sample-rate==0)");
  128. free(priv); return(NULL);
  129. }
  130. dbg(1, "ffmpeg - %s", fn);
  131. if (nfo)
  132. dbg(1, "ffmpeg - sr:%i c:%i d:%"PRIi64" f:%"PRIi64, nfo->sample_rate, nfo->channels, nfo->length, nfo->frames);
  133. return (void*) priv;
  134. }
  135. static int ad_close_ffmpeg(void *sf) {
  136. ffmpeg_audio_decoder *priv = (ffmpeg_audio_decoder*) sf;
  137. if (!priv) return -1;
  138. avcodec_close(priv->codecContext);
  139. avformat_close_input(&priv->formatContext);
  140. free(priv);
  141. return 0;
  142. }
  143. static void int16_to_float(int16_t *in, float *out, int num_channels, int num_samples, int out_offset) {
  144. int i,ii;
  145. for (i=0;i<num_samples;i++) {
  146. for (ii=0;ii<num_channels;ii++) {
  147. out[(i+out_offset)*num_channels+ii]= (float) in[i*num_channels+ii]/ 32768.0;
  148. }
  149. }
  150. }
  151. static ssize_t ad_read_ffmpeg(void *sf, float* d, size_t len) {
  152. ffmpeg_audio_decoder *priv = (ffmpeg_audio_decoder*) sf;
  153. if (!priv) return -1;
  154. size_t frames = len / priv->channels;
  155. size_t written = 0;
  156. ssize_t ret = 0;
  157. while (ret >= 0 && written < frames) {
  158. dbg(3,"loop: %i/%i (bl:%lu)",written, frames, priv->m_tmpBufferLen );
  159. if (priv->seek_frame == 0 && priv->m_tmpBufferLen > 0 ) {
  160. int s = MIN(priv->m_tmpBufferLen / priv->channels, frames - written );
  161. int16_to_float(priv->m_tmpBufferStart, d, priv->channels, s , written);
  162. written += s;
  163. priv->output_clock+=s;
  164. s = s * priv->channels;
  165. priv->m_tmpBufferStart += s;
  166. priv->m_tmpBufferLen -= s;
  167. ret = 0;
  168. } else {
  169. priv->m_tmpBufferStart = priv->m_tmpBuffer;
  170. priv->m_tmpBufferLen = 0;
  171. if (!priv->pkt_ptr || priv->pkt_len <1 ) {
  172. if (priv->packet.data) av_free_packet(&priv->packet);
  173. ret = av_read_frame(priv->formatContext, &priv->packet);
  174. if (ret<0) { dbg(1, "reached end of file."); break; }
  175. priv->pkt_len = priv->packet.size;
  176. priv->pkt_ptr = priv->packet.data;
  177. }
  178. if (priv->packet.stream_index != priv->audioStream) {
  179. priv->pkt_ptr = NULL;
  180. continue;
  181. }
  182. /* decode all chunks in packet */
  183. int data_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
  184. #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(54, 0, 0)
  185. // TODO use av_frame_alloc() and av_frame_free() with newer ffmpeg
  186. AVFrame avf;
  187. memset(&avf, 0, sizeof(AVFrame));
  188. int got_frame = 0;
  189. ret = avcodec_decode_audio4(priv->codecContext, &avf, &got_frame, &priv->packet);
  190. if (ret >= 0 && got_frame) {
  191. int ch, plane_size;
  192. const int planar = av_sample_fmt_is_planar(priv->codecContext->sample_fmt);
  193. data_size = av_samples_get_buffer_size(&plane_size, priv->codecContext->channels, avf.nb_samples, priv->codecContext->sample_fmt, 1);
  194. if (data_size <= AVCODEC_MAX_AUDIO_FRAME_SIZE) {
  195. memcpy(priv->m_tmpBuffer, avf.extended_data[0], plane_size);
  196. if (planar && priv->codecContext->channels > 1) {
  197. uint8_t *out = ((uint8_t *)priv->m_tmpBuffer) + plane_size;
  198. for (ch = 1; ch < priv->codecContext->channels; ch++) {
  199. memcpy(out, avf.extended_data[ch], plane_size);
  200. out += plane_size;
  201. }
  202. }
  203. }
  204. } else {
  205. ret = -1;
  206. }
  207. #elif LIBAVUTIL_VERSION_INT > AV_VERSION_INT(49, 15, 0) && LIBAVCODEC_VERSION_INT > AV_VERSION_INT(52, 20, 1) // ??
  208. // this was deprecated in LIBAVCODEC_VERSION_MAJOR 53
  209. ret = avcodec_decode_audio3(priv->codecContext,
  210. priv->m_tmpBuffer, &data_size, &priv->packet);
  211. #else
  212. int len = priv->packet.size;
  213. uint8_t *ptr = priv->packet.data;
  214. ret = avcodec_decode_audio2(priv->codecContext,
  215. priv->m_tmpBuffer, &data_size, ptr, len);
  216. #endif
  217. if (ret < 0 || ret > priv->pkt_len) {
  218. #if 0
  219. dbg(0, "audio decode error");
  220. return -1;
  221. #endif
  222. priv->pkt_len=0;
  223. ret=0;
  224. continue;
  225. }
  226. priv->pkt_len -= ret; priv->pkt_ptr += ret;
  227. /* sample exact alignment */
  228. if (priv->packet.pts != AV_NOPTS_VALUE) {
  229. priv->decoder_clock = priv->samplerate * av_q2d(priv->formatContext->streams[priv->audioStream]->time_base) * priv->packet.pts;
  230. } else {
  231. dbg(0, "!!! NO PTS timestamp in file");
  232. priv->decoder_clock += (data_size>>1) / priv->channels;
  233. }
  234. if (data_size>0) {
  235. priv->m_tmpBufferLen+= (data_size>>1); // 2 bytes per sample
  236. }
  237. /* align buffer after seek. */
  238. if (priv->seek_frame > 0) {
  239. const int diff = priv->output_clock-priv->decoder_clock;
  240. if (diff<0) {
  241. /* seek ended up past the wanted sample */
  242. dbg(0, " !!! Audio seek failed.");
  243. return -1;
  244. } else if (priv->m_tmpBufferLen < (diff*priv->channels)) {
  245. /* wanted sample not in current buffer - keep going */
  246. dbg(2, " !!! seeked sample was not in decoded buffer. frames-to-go: %li", diff);
  247. priv->m_tmpBufferLen = 0;
  248. } else if (diff!=0 && data_size > 0) {
  249. /* wanted sample is in current buffer but not at the beginnning */
  250. dbg(2, " !!! sync buffer to seek. (diff:%i)", diff);
  251. priv->m_tmpBufferStart+= diff*priv->codecContext->channels;
  252. priv->m_tmpBufferLen -= diff*priv->codecContext->channels;
  253. #if 1
  254. memmove(priv->m_tmpBuffer, priv->m_tmpBufferStart, priv->m_tmpBufferLen);
  255. priv->m_tmpBufferStart = priv->m_tmpBuffer;
  256. #endif
  257. priv->seek_frame=0;
  258. priv->decoder_clock += diff;
  259. } else if (data_size > 0) {
  260. dbg(2, "Audio exact sync-seek (%"PRIi64" == %"PRIi64")", priv->decoder_clock, priv->seek_frame);
  261. priv->seek_frame=0;
  262. } else {
  263. dbg(0, "Error: no audio data in packet");
  264. }
  265. }
  266. //dbg(0, "PTS: decoder:%"PRIi64". - want: %"PRIi64, priv->decoder_clock, priv->output_clock);
  267. //dbg(0, "CLK: frame: %"PRIi64" T:%.3fs",priv->decoder_clock, (float) priv->decoder_clock/priv->samplerate);
  268. }
  269. }
  270. if (written!=frames) {
  271. dbg(2, "short-read");
  272. }
  273. return written * priv->channels;
  274. }
  275. static int64_t ad_seek_ffmpeg(void *sf, int64_t pos) {
  276. ffmpeg_audio_decoder *priv = (ffmpeg_audio_decoder*) sf;
  277. if (!sf) return -1;
  278. if (pos == priv->output_clock) return pos;
  279. /* flush internal buffer */
  280. priv->m_tmpBufferLen = 0;
  281. priv->seek_frame = pos;
  282. priv->output_clock = pos;
  283. priv->pkt_len = 0; priv->pkt_ptr = NULL;
  284. priv->decoder_clock = 0;
  285. #if 0
  286. /* TODO seek at least 1 packet before target.
  287. * for mpeg compressed files, the
  288. * output may depend on past frames! */
  289. if (pos > 8192) pos -= 8192;
  290. else pos = 0;
  291. #endif
  292. const int64_t timestamp = pos / av_q2d(priv->formatContext->streams[priv->audioStream]->time_base) / priv->samplerate;
  293. dbg(2, "seek frame:%"PRIi64" - idx:%"PRIi64, pos, timestamp);
  294. av_seek_frame(priv->formatContext, priv->audioStream, timestamp, AVSEEK_FLAG_ANY | AVSEEK_FLAG_BACKWARD);
  295. avcodec_flush_buffers(priv->codecContext);
  296. return pos;
  297. }
  298. static int ad_eval_ffmpeg(const char *f) {
  299. char *ext = strrchr(f, '.');
  300. if (!ext) return 10;
  301. // libavformat.. guess_format..
  302. return 40;
  303. }
  304. #endif
  305. static const ad_plugin ad_ffmpeg = {
  306. #ifdef HAVE_FFMPEG
  307. &ad_eval_ffmpeg,
  308. &ad_open_ffmpeg,
  309. &ad_close_ffmpeg,
  310. &ad_info_ffmpeg,
  311. &ad_seek_ffmpeg,
  312. &ad_read_ffmpeg,
  313. &ad_bitrate_null
  314. #else
  315. &ad_eval_null,
  316. &ad_open_null,
  317. &ad_close_null,
  318. &ad_info_null,
  319. &ad_seek_null,
  320. &ad_read_null,
  321. &ad_bitrate_null
  322. #endif
  323. };
  324. /* dlopen handler */
  325. const ad_plugin * adp_get_ffmpeg() {
  326. #ifdef HAVE_FFMPEG
  327. static int ffinit = 0;
  328. if (!ffinit) {
  329. ffinit=1;
  330. #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53, 5, 0)
  331. avcodec_init();
  332. #endif
  333. av_register_all();
  334. avcodec_register_all();
  335. if(ad_debug_level <= 1)
  336. av_log_set_level(AV_LOG_QUIET);
  337. else
  338. av_log_set_level(AV_LOG_VERBOSE);
  339. }
  340. #endif
  341. return &ad_ffmpeg;
  342. }