1 /* media-ffmpeg.c - analyse audio files or streams via ffmpeg
3 Copyright (C) 2006 Sebastian Freundt
5 This file is part of SXEmacs
7 SXEmacs is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 SXEmacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
21 /* Synched up with: Not in FSF. */
34 #if defined HAVE_STDINT_H
36 #endif /* HAVE_STDINT_H */
42 #include "media-ffmpeg.h"
44 static int media_ffmpeg_bitrate(AVCodecContext*);
45 static AVFormatContext *media_ffmpeg_open_file(const char*);
46 AVFormatContext *media_ffmpeg_open_data(char*, size_t);
48 static void media_ffmpeg_analyse_audio(media_substream*, AVFormatContext*, int);
49 static void media_ffmpeg_analyse_video(media_substream*, AVFormatContext*, int);
51 #define MYSELF MDRIVER_FFMPEG
55 #define __FFMPEG_DEBUG__(args...) fprintf(stderr, "FFMPEG " args)
56 #ifndef FFMPEG_DEBUG_FLAG
57 #define FFMPEG_DEBUG(args...)
59 #define FFMPEG_DEBUG(args...) __FFMPEG_DEBUG__(args)
61 #define FFMPEG_DEBUG_AVF(args...) FFMPEG_DEBUG("[avformat]: " args)
62 #define FFMPEG_DEBUG_AVC(args...) FFMPEG_DEBUG("[avcodec]: " args)
63 #define FFMPEG_DEBUG_AVS(args...) FFMPEG_DEBUG("[stream]: " args)
64 #define FFMPEG_CRITICAL(args...) __FFMPEG_DEBUG__("CRITICAL: " args)
67 DECLARE_MEDIA_DRIVER_OPEN_METH(media_ffmpeg);
68 DECLARE_MEDIA_DRIVER_CLOSE_METH(media_ffmpeg);
69 DECLARE_MEDIA_DRIVER_PRINT_METH(media_ffmpeg);
70 DECLARE_MEDIA_DRIVER_READ_METH(media_ffmpeg);
71 DECLARE_MEDIA_DRIVER_REWIND_METH(media_ffmpeg);
73 DEFINE_MEDIA_DRIVER_CUSTOM(media_ffmpeg,
74 media_ffmpeg_open, media_ffmpeg_close,
75 media_ffmpeg_print, NULL,
76 media_ffmpeg_read, NULL,
77 media_ffmpeg_rewind, NULL);
79 DECLARE_MEDIA_DRIVER_OPEN_METH(new_media_ffmpeg);
80 DECLARE_MEDIA_DRIVER_READ_METH(new_media_ffmpeg);
81 DECLARE_MEDIA_DRIVER_REWIND_METH(new_media_ffmpeg);
83 DEFINE_MEDIA_DRIVER_CUSTOM(new_media_ffmpeg,
84 new_media_ffmpeg_open, NULL,
86 new_media_ffmpeg_read, NULL,
87 new_media_ffmpeg_rewind, NULL);
91 media_ffmpeg_bitrate(AVCodecContext *enc)
95 /* for PCM codecs, compute bitrate directly */
96 switch ((unsigned int)enc->codec_id) {
97 case CODEC_ID_PCM_S32LE:
98 case CODEC_ID_PCM_S32BE:
99 case CODEC_ID_PCM_U32LE:
100 case CODEC_ID_PCM_U32BE:
101 bitrate = enc->sample_rate * enc->channels * 32;
103 case CODEC_ID_PCM_S24LE:
104 case CODEC_ID_PCM_S24BE:
105 case CODEC_ID_PCM_U24LE:
106 case CODEC_ID_PCM_U24BE:
107 case CODEC_ID_PCM_S24DAUD:
108 bitrate = enc->sample_rate * enc->channels * 24;
110 case CODEC_ID_PCM_S16LE:
111 case CODEC_ID_PCM_S16BE:
112 case CODEC_ID_PCM_U16LE:
113 case CODEC_ID_PCM_U16BE:
114 bitrate = enc->sample_rate * enc->channels * 16;
116 case CODEC_ID_PCM_S8:
117 case CODEC_ID_PCM_U8:
118 case CODEC_ID_PCM_ALAW:
119 case CODEC_ID_PCM_MULAW:
120 bitrate = enc->sample_rate * enc->channels * 8;
123 bitrate = enc->bit_rate;
129 char *media_ffmpeg_streaminfo(Lisp_Media_Stream *ms)
131 AVFormatContext *avfc = NULL;
133 int chars_left = 4095;
135 avfc = media_stream_data(ms);
136 out = xmalloc_atomic(chars_left+1);
139 /* cannot use ffmpeg on corrupt streams */
140 if (media_stream_driver(ms) != MYSELF || avfc == NULL)
143 if (avfc->author && *avfc->author) {
144 strcat(out, " :author \"");
145 strncat(out, avfc->author, chars_left);
149 if (avfc->title && *avfc->title) {
150 strcat(out, " :title: \"");
151 strncat(out, avfc->title, chars_left);
157 strcat(out, " :year ");
158 snprintf(year, 12, "%d", avfc->year);
159 strncat(out, year, chars_left);
167 media_ffmpeg_print(Lisp_Object ms, Lisp_Object pcfun, int ef)
172 static AVFormatContext*
173 media_ffmpeg_open_file(const char *file)
175 #if defined HAVE_AVFORMAT_ALLOC_CONTEXT
176 AVFormatContext *avfc = avformat_alloc_context();
177 #elif defined HAVE_AV_ALLOC_FORMAT_CONTEXT
178 /* deprecated already, but `people' like Horst still use this */
179 AVFormatContext *avfc = av_alloc_format_context();
181 # error "Your ffmpeg library is too old. Adopt a new one."
182 #endif /* HAVE_AVFORMAT_ALLOC_CONTEXT */
185 if (av_open_input_file(&avfc, file, NULL, 0, NULL) < 0) {
186 FFMPEG_DEBUG_AVF("opening file failed.\n");
192 /* Retrieve stream information */
193 if (av_find_stream_info(avfc) < 0) {
194 FFMPEG_DEBUG_AVS("opening stream inside file failed.\n");
195 av_close_input_file(avfc);
206 media_ffmpeg_vio_open(URLContext *h, const char *filename, int flags)
212 media_ffmpeg_vio_read(URLContext *h, unsigned char *buf, int size)
214 media_data *sd = (media_data*)h->priv_data;
216 FFMPEG_DEBUG_AVS("reading %d bytes to 0x%x, respecting seek %ld\n",
217 size, (unsigned int)buf, sd->seek);
219 if ((long int)sd->length <= sd->seek) {
220 FFMPEG_DEBUG_AVS("eof\n");
224 memcpy(buf, sd->data+sd->seek, size);
231 media_ffmpeg_vio_write(URLContext *h, unsigned char *buf, int size)
237 media_ffmpeg_vio_seek(URLContext *h, int64_t pos, int whence)
239 media_data *sd = (media_data*)h->priv_data;
241 FFMPEG_DEBUG_AVS("seeking to %ld via %d\n", (long int)pos, whence);
248 sd->seek = sd->seek+pos;
251 sd->seek = sd->length+pos;
261 media_ffmpeg_vio_close(URLContext *h)
269 /* this is a memory-i/o protocol in case we have to deal with string data */
270 static URLProtocol media_ffmpeg_protocol = {
272 media_ffmpeg_vio_open,
273 media_ffmpeg_vio_read,
274 media_ffmpeg_vio_write,
275 media_ffmpeg_vio_seek,
276 media_ffmpeg_vio_close,
279 /** Size of probe buffer, for guessing file type from file contents. */
280 #define PROBE_BUF_MIN 2048
281 #define PROBE_BUF_MAX 131072
284 media_ffmpeg_open_data(char *data, size_t size)
286 #if defined HAVE_AVFORMAT_ALLOC_CONTEXT
287 AVFormatContext *avfc = avformat_alloc_context();
288 #elif defined HAVE_AV_ALLOC_FORMAT_CONTEXT
289 /* deprecated already, but `people' like Horst still use this */
290 AVFormatContext *avfc = av_alloc_format_context();
292 # error "Your ffmpeg library is too old. Adopt a new one."
293 #endif /* HAVE_AVFORMAT_ALLOC_CONTEXT */
294 AVProbeData *pd = NULL;
295 ByteIOContext *bioctx = NULL;
296 AVInputFormat *fmt = NULL;
297 char file[] = "SXEmff:SXEmacs.mp3\000";
298 media_data *sd = NULL;
300 /* register our virtual i/o */
301 #if defined HAVE_AV_REGISTER_PROTOCOL
302 av_register_protocol(&media_ffmpeg_protocol);
303 #elif defined HAVE_REGISTER_PROTOCOL
304 register_protocol(&media_ffmpeg_protocol);
306 # error "Get a recent ffmpeg or get a life."
309 /* initialise our media_data */
310 sd = xnew_and_zero(media_data);
315 /* register ffmpeg byteio */
316 bioctx = xnew_and_zero(ByteIOContext);
317 #if defined FFMPEG_URL_FOPEN_BIOCTX_STAR_STAR
318 url_fopen(&bioctx, file, URL_RDONLY);
319 #elif defined FFMPEG_URL_FOPEN_BIOCTX_STAR
320 url_fopen(bioctx, file, URL_RDONLY);
322 /* erm, register us at the byteio context */
323 ((URLContext*)(bioctx->opaque))->priv_data = sd;
326 pd = xnew_and_zero(AVProbeData);
331 pd->buf = (void*)sd->data;
332 pd->buf_size = PROBE_BUF_MIN;
333 fmt = av_probe_input_format(pd, 1);
335 /* if still no format found, error */
345 if (av_open_input_stream(&avfc, bioctx, file, fmt, NULL) < 0) {
353 /* Retrieve stream information */
354 if (av_find_stream_info(avfc) < 0) {
366 media_ffmpeg_close(ms_driver_data_t data)
368 AVFormatContext *avfc = (AVFormatContext*)data;
369 FFMPEG_DEBUG_AVF("closing AVFormatContext: 0x%lx\n",
370 (long unsigned int)avfc);
371 if (avfc && avfc->iformat)
372 av_close_input_file(avfc);
376 media_ffmpeg_analyse_audio(media_substream *mss, AVFormatContext *avfc, int st)
378 mtype_audio_properties *mtap;
379 const char *name = NULL;
380 const char *codec_name = NULL;
381 /* libavformat cruft */
383 AVCodecContext *avcc;
385 /* unpack the stream and codec context from the container, again */
386 avst = avfc->streams[st];
390 mtap = xnew_and_zero(mtype_audio_properties);
393 if (avfc && avfc->iformat)
394 name = avfc->iformat->name;
395 if (avcc && avcc->codec)
396 codec_name = avcc->codec->name;
399 mtap->codec_name = codec_name;
400 mtap->channels = avcc->channels;
401 mtap->samplerate = avcc->sample_rate;
402 mtap->bitrate = media_ffmpeg_bitrate(avcc);
404 /* samplewidth and framesize */
405 switch (avcc->sample_fmt) {
407 mtap->samplewidth = 8;
408 mtap->framesize = mtap->channels * 1;
409 mtap->msf = sxe_msf_U8;
412 mtap->samplewidth = 16;
413 mtap->framesize = mtap->channels * 2;
414 mtap->msf = sxe_msf_S16;
416 #if defined SAMPLE_FMT_S24
418 mtap->samplewidth = 32;
419 mtap->framesize = mtap->channels * 4;
420 mtap->msf = sxe_msf_S24;
422 #endif /* SAMPLE_FMT_S24 */
424 mtap->samplewidth = 32;
425 mtap->framesize = mtap->channels * 4;
426 mtap->msf = sxe_msf_S32;
429 mtap->samplewidth = 8*sizeof(float);
430 mtap->framesize = mtap->channels * sizeof(float);
431 mtap->msf = sxe_msf_FLT;
433 case SAMPLE_FMT_NONE:
435 mtap->samplewidth = 0;
438 mtap->endianness = 0;
441 media_substream_type_properties(mss).aprops = mtap;
442 media_substream_data(mss) = (void*)st;
446 media_ffmpeg_analyse_video(media_substream *mss, AVFormatContext *avfc, int st)
448 mtype_video_properties *mtvp;
449 const char *name = NULL;
450 const char *codec_name = NULL;
451 /* libavformat cruft */
453 AVCodecContext *avcc;
455 /* unpack the stream and codec context from the container, again */
456 avst = avfc->streams[st];
460 mtvp = xnew_and_zero(mtype_video_properties);
463 if (avfc && avfc->iformat)
464 name = avfc->iformat->name;
465 if (avcc && avcc->codec)
466 codec_name = avcc->codec->name;
469 mtvp->codec_name = codec_name;
470 mtvp->bitrate = avcc->bit_rate;
471 mtvp->width = avcc->width;
472 mtvp->height = avcc->height;
473 mtvp->aspect_num = avcc->sample_aspect_ratio.num;
474 mtvp->aspect_den = avcc->sample_aspect_ratio.den;
476 mtvp->endianness = 0;
479 media_substream_type_properties(mss).vprops = mtvp;
480 media_substream_data(mss) = (void*)st;
483 /* main analysis function */
484 static ms_driver_data_t
485 media_ffmpeg_open(Lisp_Media_Stream *ms)
488 media_substream *mss;
489 /* libavformat stuff */
490 AVFormatContext *avfc = NULL;
491 AVStream *avst = NULL;
492 AVCodecContext *avcc = NULL;
498 switch (media_stream_kind(ms)) {
500 mkind_file_properties *mkfp = NULL;
505 mkfp = media_stream_kind_properties(ms).fprops;
506 TO_EXTERNAL_FORMAT(LISP_STRING, mkfp->filename,
507 ALLOCA, (file, file_len), Qnil);
508 avfc = media_ffmpeg_open_file(file);
510 media_stream_set_meths(ms, NULL);
511 media_stream_driver(ms) = MDRIVER_UNKNOWN;
515 /* store the filesize */
516 mkfp->filesize = avfc->file_size;
520 mkind_string_properties *mksp = NULL;
525 mksp = media_stream_kind_properties(ms).sprops;
526 data = mksp->stream_data;
528 avfc = media_ffmpeg_open_data(data, size);
531 media_stream_set_meths(ms, NULL);
532 media_stream_driver(ms) = MDRIVER_UNKNOWN;
540 case NUMBER_OF_MEDIA_KINDS:
545 /* check if there is at least one usable stream */
546 for (size_t st = 0; st < avfc->nb_streams; st++) {
547 avst = avfc->streams[st];
550 avcc->codec_id != CODEC_ID_NONE &&
551 avcc->codec_type != CODEC_TYPE_DATA &&
552 (avc = avcodec_find_decoder(avcc->codec_id)) &&
553 (avc && (avcodec_open(avcc, avc) >= 0))) {
555 /* create a substream */
556 mss = make_media_substream_append(ms);
558 switch ((unsigned int)avcc->codec_type) {
559 case CODEC_TYPE_VIDEO:
560 /* assign substream props */
561 media_substream_type(mss) = MTYPE_VIDEO;
562 media_ffmpeg_analyse_video(mss, avfc, st);
564 case CODEC_TYPE_AUDIO:
565 /* assign substream props */
566 media_substream_type(mss) = MTYPE_AUDIO;
567 media_ffmpeg_analyse_audio(mss, avfc, st);
568 /* set some stream handlers */
569 media_stream_set_meths(ms, media_ffmpeg);
571 case CODEC_TYPE_DATA:
572 media_substream_type(mss) = MTYPE_IMAGE;
575 media_substream_type(mss) = MTYPE_UNKNOWN;
581 /* keep the format context */
582 media_stream_data(ms) = avfc;
584 /* set me as driver indicator */
585 media_stream_driver(ms) = MYSELF;
592 handle_packet(AVFormatContext *avfc, AVPacket *pkt)
597 int ret, got_picture;
599 st = avfc->streams[pkt->stream_index];
601 /* XXX: allocate picture correctly */
602 avcodec_get_frame_defaults(&picture);
604 ret = avcodec_decode_video(
605 st->codec, &picture, &got_picture, pkt->data, pkt->size);
613 FFMPEG_DEBUG_AVF("got video frame\n");
623 media_ffmpeg_read(media_substream *mss, void *outbuf, size_t length)
625 /* read at most `length' frames into `outbuf' */
626 /* convert them to internal format */
628 Lisp_Media_Stream *ms = mss->up;
629 mtype_audio_properties *mtap;
630 media_sample_format_t *fmt;
632 AVFormatContext *avfc;
634 AVCodecContext *avcc;
638 /* the size we present here, is _not_ the size we want, however
639 * ffmpeg is quite pedantic about the buffer size,
640 * we just pass the least possible value here to please him */
641 int size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
644 long int bufseek = 0, si = -1;
645 int declen, dec, rf_status = 0;
647 /* check the integrity of the media stream */
648 if (media_stream_driver(ms) != MYSELF)
651 /* fetch the format context */
652 avfc = media_stream_data(ms);
657 si = (long int)mss->substream_data;
658 avst = avfc->streams[si];
662 /* unpack the substream */
663 if ((mtap = media_substream_type_properties(mss).aprops) == NULL) {
664 FFMPEG_DEBUG_AVS("stream information missing. Uh Oh.\n");
668 /* fetch audio info */
669 framesize = mtap->framesize;
672 /* initialise the packet */
673 pkt.pts = pkt.dts = pkt.size = 0;
674 FFMPEG_DEBUG_AVF("initialised packet: "
675 "pts:%lld dts:%lld psz:%d\n",
676 (long long int)pkt.pts,
677 (long long int)pkt.dts,
680 /* read a frame and decode it */
681 while ((size_t)bufseek <= length*framesize &&
682 (rf_status = av_read_frame(avfc, &pkt)) >= 0) {
683 if (pkt.stream_index != si) {
684 FFMPEG_DEBUG_AVF("SKIP reason: "
685 "sought after stream %ld, got %ld\n",
687 (long int)pkt.stream_index);
688 handle_packet(avfc, &pkt);
692 FFMPEG_DEBUG_AVF("read frame: "
693 "pts:%lld dts:%lld psz:%d\n",
694 (long long int)pkt.pts,
695 (long long int)pkt.dts,
699 /* decode the demuxed packet */
700 #ifdef HAVE_AVCODEC_DECODE_AUDIO2
701 /* prefer decode_audio2() if available */
702 size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
703 declen = avcodec_decode_audio2(
704 avcc, (void*)((char*)outbuf+bufseek),
705 &size, pkt.data, pkt.size);
706 #elif defined HAVE_AVCODEC_DECODE_AUDIO
707 declen = avcodec_decode_audio(
708 avcc, (void*)((char*)outbuf+bufseek),
709 &size, pkt.data, pkt.size);
714 if (dec > 0 && size > 0) {
715 FFMPEG_DEBUG_AVF("pts:%lld dts:%lld psz:%d s:%d d:%d\n",
716 (long long int)pkt.pts,
717 (long long int)pkt.dts,
718 pkt.size, size, declen);
720 /* memcpy(outbuf+bufseek, (char*)buffer, size); */
724 FFMPEG_DEBUG_AVF("packet state: "
725 "pts:%lld dts:%lld psz:%d\n",
726 (long long int)pkt.pts,
727 (long long int)pkt.dts,
729 av_free_packet(&pkt);
731 av_free_packet(&pkt);
733 FFMPEG_DEBUG_AVF("finished reading, bufseek=%ld, rf_status=%ld\n",
734 (long int)bufseek, (long int)rf_status);
736 /* convert the pig */
737 size = bufseek/framesize;
738 MEDIA_SAMPLE_FORMAT_UPSAMPLE(fmt)(outbuf, outbuf, size*mtap->channels);
745 media_ffmpeg_rewind(media_substream *mss)
747 /* rewind the stream to the first frame */
749 AVFormatContext *avfc;
751 Lisp_Media_Stream *ms = mss->up;
756 /* check the integrity of the media stream */
757 if (media_stream_driver(ms) != MYSELF)
760 FFMPEG_DEBUG_AVF("rewind substream 0x%lx\n",
761 (long unsigned int)mss);
763 /* fetch the format context */
764 if (!(avfc = media_stream_data(ms)))
767 si = (long int)mss->substream_data;
768 avst = avfc->streams[si];
769 if ((start_time = avst->start_time) < 0) {
773 FFMPEG_DEBUG_AVF("rewind (idx:%ld) to %lld\n",
774 si, (long long int)start_time);
776 /* ... and reset the stream */
777 res = av_seek_frame(avfc, si, AV_NOPTS_VALUE, AVSEEK_FLAG_BACKWARD);
780 FFMPEG_DEBUG_AVF("rewind succeeded\n");
783 FFMPEG_DEBUG_AVF("rewind exitted with %d\n", res);
790 * the size must be big enough to compensate the hardware audio buffersize size
792 #define SAMPLE_ARRAY_SIZE (2*65536)
793 #define VIDEO_PICTURE_QUEUE_SIZE 1
794 #define SUBPICTURE_QUEUE_SIZE 4
795 #define AUDIO_DIFF_AVG_NB 20
796 #define SDL_AUDIO_BUFFER_SIZE 1024
798 #define MAX_VIDEOQ_SIZE (5 * 256 * 1024)
799 #define MAX_AUDIOQ_SIZE (5 * 16 * 1024)
800 #define MAX_SUBTITLEQ_SIZE (5 * 16 * 1024)
802 #define FF_ALLOC_EVENT 0
803 #define FF_REFRESH_EVENT 1
804 #define FF_QUIT_EVENT 2
806 typedef struct PacketQueue {
807 AVPacketList *first_pkt, *last_pkt;
811 struct sxe_semaphore_s sem;
814 typedef struct VideoPicture {
815 /* presentation time stamp for this picture */
818 int width, height; /* source height & width */
822 typedef struct SubPicture {
823 double pts; /* presentation time stamp for this picture */
827 typedef struct VideoState {
830 AVInputFormat *iformat;
839 int dtg_active_format;
844 double external_clock; /* external clock base */
845 int64_t external_clock_time;
848 double audio_diff_cum; /* used for AV difference average computation */
849 double audio_diff_avg_coef;
850 double audio_diff_threshold;
851 int audio_diff_avg_count;
854 int audio_hw_buf_size;
855 /* samples output by the codec. we reserve more space for avsync
857 uint8_t audio_buf[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2]
858 /* fixme, this is very gcc centric, what's aligned(x) in icc? */
859 __attribute__((aligned(16)));
860 unsigned int audio_buf_size; /* in bytes */
861 int audio_buf_index; /* in bytes */
863 uint8_t *audio_pkt_data;
866 int show_audio; /* if true, display audio samples */
867 int16_t sample_array[SAMPLE_ARRAY_SIZE];
868 int sample_array_index;
873 int subtitle_stream_changed;
874 AVStream *subtitle_st;
875 PacketQueue subtitleq;
876 SubPicture subpq[SUBPICTURE_QUEUE_SIZE];
877 int subpq_size, subpq_rindex, subpq_windex;
878 struct sxe_semaphore_s subpq_sem;
881 double frame_last_pts;
882 double frame_last_delay;
883 /* pts of last decoded frame / predicted pts of next decoded frame */
888 /* current displayed pts (different from video_clock
889 * if frame fifos are used */
890 double video_current_pts;
891 /* time (av_gettime) at which we updated video_current_pts - used
892 * to have running video pts */
893 int64_t video_current_pts_time;
894 VideoPicture pictq[VIDEO_PICTURE_QUEUE_SIZE];
895 int pictq_size, pictq_rindex, pictq_windex;
896 struct sxe_semaphore_s pictq_sem;
898 /* QETimer *video_timer; */
902 int width, height, xleft, ytop;
905 /* since we have only one decoding thread, we can use a global
906 variable instead of a thread local variable */
907 static VideoState *global_video_state;
910 /* packet queue handling */
912 packet_queue_init(PacketQueue *q)
914 memset(q, 0, sizeof(PacketQueue));
915 SXE_SEMAPH_INIT(&q->sem);
919 packet_queue_flush(PacketQueue *q)
921 AVPacketList *pkt, *pkt1;
923 SXE_SEMAPH_LOCK(&q->sem);
924 for (pkt = q->first_pkt; pkt != NULL; pkt = pkt1) {
926 av_free_packet(&pkt->pkt);
933 SXE_SEMAPH_UNLOCK(&q->sem);
937 packet_queue_end(PacketQueue *q)
939 packet_queue_flush(q);
940 SXE_SEMAPH_FINI(&q->sem);
944 packet_queue_put(PacketQueue *q, AVPacket *pkt)
948 /* duplicate the packet */
949 if (pkt!=&flush_pkt && av_dup_packet(pkt) < 0)
952 pkt1 = av_malloc(sizeof(AVPacketList));
959 SXE_SEMAPH_LOCK(&q->sem);
965 q->last_pkt->next = pkt1;
968 q->size += pkt1->pkt.size;
969 /* XXX: should duplicate packet data in DV case */
970 SXE_SEMAPH_SIGNAL(&q->sem);
971 SXE_SEMAPH_UNLOCK(&q->sem);
976 packet_queue_abort(PacketQueue *q)
978 SXE_SEMAPH_LOCK(&q->sem);
980 q->abort_request = 1;
982 SXE_SEMAPH_SIGNAL(&q->sem);
983 SXE_SEMAPH_UNLOCK(&q->sem);
986 /* return < 0 if aborted, 0 if no packet and > 0 if packet. */
988 packet_queue_get(PacketQueue *q, AVPacket *pkt, int block)
989 __attribute__((unused));
992 packet_queue_get(PacketQueue *q, AVPacket *pkt, int block)
997 SXE_SEMAPH_LOCK(&q->sem);
1000 if (q->abort_request) {
1005 pkt1 = q->first_pkt;
1007 q->first_pkt = pkt1->next;
1011 q->size -= pkt1->pkt.size;
1016 } else if (!block) {
1020 SXE_SEMAPH_WAIT(&q->sem);
1023 SXE_SEMAPH_UNLOCK(&q->sem);
1027 static uint64_t global_video_pkt_pts = AV_NOPTS_VALUE;
1030 my_get_buffer(struct AVCodecContext *c, AVFrame *pic)
1032 int ret= avcodec_default_get_buffer(c, pic);
1033 uint64_t *pts= av_malloc(sizeof(uint64_t));
1034 *pts= global_video_pkt_pts;
1040 my_release_buffer(struct AVCodecContext *c, AVFrame *pic)
1042 if(pic) av_freep(&pic->opaque);
1043 avcodec_default_release_buffer(c, pic);
1048 stream_component_open(VideoState *is, int stream_index, Lisp_Media_Stream *ms)
1051 media_substream *mss = NULL;
1052 AVFormatContext *ic = is->ic;
1053 AVCodecContext *enc;
1056 if (stream_index < 0 || (size_t)stream_index >= ic->nb_streams) {
1059 enc = ic->streams[stream_index]->codec;
1061 /* prepare audio output */
1062 if (enc->codec_type == CODEC_TYPE_AUDIO) {
1064 wanted_spec.freq = enc->sample_rate;
1065 wanted_spec.format = AUDIO_S16SYS;
1067 /* hack for AC3. XXX: suppress that */
1068 if (enc->channels > 2)
1071 wanted_spec.channels = enc->channels;
1072 wanted_spec.silence = 0;
1073 wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;
1074 wanted_spec.callback = sdl_audio_callback;
1075 wanted_spec.userdata = is;
1077 is->audio_hw_buf_size = 0 /* spec.size */;
1080 codec = avcodec_find_decoder(enc->codec_id);
1081 enc->debug_mv = 0 /* debug_mv */;
1082 enc->debug = 0 /* debug */;
1083 enc->workaround_bugs = 0 /* workaround_bugs */;
1084 enc->lowres = 0 /* lowres */;
1086 enc->flags |= CODEC_FLAG_EMU_EDGE;
1087 enc->idct_algo = FF_IDCT_AUTO; /* idct; */
1089 enc->flags2 |= CODEC_FLAG2_FAST;
1090 enc->skip_frame = AVDISCARD_DEFAULT; /* skip_frame; */
1091 enc->skip_idct = AVDISCARD_DEFAULT; /* skip_idct; */
1092 enc->skip_loop_filter = AVDISCARD_DEFAULT; /* skip_loop_filter; */
1094 enc->error_resilience = FF_ER_CAREFUL; /* error_resilience; */
1096 enc->error_concealment = 3; /* error_concealment; */
1098 avcodec_open(enc, codec) < 0)
1100 if (1 /* thread_count */ > 1)
1101 avcodec_thread_init(enc, 1 /*thread_count*/);
1102 enc->thread_count= 1 /* thread_count */;
1104 /* create a substream */
1105 mss = make_media_substream_append(ms);
1107 switch ((unsigned int)enc->codec_type) {
1108 case CODEC_TYPE_AUDIO:
1109 is->audio_stream = stream_index;
1110 is->audio_st = ic->streams[stream_index];
1111 is->audio_buf_size = 0;
1112 is->audio_buf_index = 0;
1114 /* init averaging filter */
1115 is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
1116 is->audio_diff_avg_count = 0;
1117 /* since we do not have a precise anough audio fifo fullness,
1118 we correct audio sync only if larger than this threshold */
1119 is->audio_diff_threshold =
1120 2.0 * SDL_AUDIO_BUFFER_SIZE / enc->sample_rate;
1122 memset(&is->audio_pkt, 0, sizeof(is->audio_pkt));
1123 packet_queue_init(&is->audioq);
1125 media_substream_type(mss) = MTYPE_AUDIO;
1126 media_ffmpeg_analyse_audio(mss, is->ic, stream_index);
1128 case CODEC_TYPE_VIDEO:
1129 is->video_stream = stream_index;
1130 is->video_st = ic->streams[stream_index];
1132 is->frame_last_delay = 40e-3;
1134 int64_t tmp = av_gettime();
1135 is->frame_timer = (double)tmp / 1000000.0f;
1137 is->video_current_pts_time = av_gettime();
1139 packet_queue_init(&is->videoq);
1140 is->video_tid = 0 /* SDL_CreateThread(video_thread, is) */;
1142 enc-> get_buffer= my_get_buffer;
1143 enc->release_buffer= my_release_buffer;
1145 media_substream_type(mss) = MTYPE_VIDEO;
1146 media_ffmpeg_analyse_video(mss, is->ic, stream_index);
1148 case CODEC_TYPE_SUBTITLE:
1149 is->subtitle_stream = stream_index;
1150 is->subtitle_st = ic->streams[stream_index];
1151 packet_queue_init(&is->subtitleq);
1153 is->subtitle_tid = 0 /*SDL_CreateThread(subtitle_thread, is)*/;
1162 stream_component_close(VideoState *is, int stream_index)
1164 AVFormatContext *ic = is->ic;
1165 AVCodecContext *enc;
1167 if (stream_index < 0 || (size_t)stream_index >= ic->nb_streams) {
1170 enc = ic->streams[stream_index]->codec;
1172 switch ((unsigned int)enc->codec_type) {
1173 case CODEC_TYPE_AUDIO:
1174 packet_queue_abort(&is->audioq);
1178 packet_queue_end(&is->audioq);
1180 case CODEC_TYPE_VIDEO:
1181 packet_queue_abort(&is->videoq);
1183 /* note: we also signal this mutex to make sure we deblock the
1184 video thread in all cases */
1185 SXE_SEMAPH_LOCK(&is->pictq_sem);
1186 SXE_SEMAPH_SIGNAL(&is->pictq_sem);
1187 SXE_SEMAPH_UNLOCK(&is->pictq_sem);
1189 SDL_WaitThread(is->video_tid, NULL);
1191 packet_queue_end(&is->videoq);
1193 case CODEC_TYPE_SUBTITLE:
1194 packet_queue_abort(&is->subtitleq);
1196 /* note: we also signal this mutex to make sure we deblock the
1197 video thread in all cases */
1198 SXE_SEMAPH_LOCK(&is->subpq_sem);
1199 is->subtitle_stream_changed = 1;
1201 SXE_SEMAPH_SIGNAL(&is->subpq_sem);
1202 SXE_SEMAPH_UNLOCK(&is->subpq_sem);
1204 SDL_WaitThread(is->subtitle_tid, NULL);
1206 packet_queue_end(&is->subtitleq);
1213 switch ((unsigned int)enc->codec_type) {
1214 case CODEC_TYPE_AUDIO:
1215 is->audio_st = NULL;
1216 is->audio_stream = -1;
1218 case CODEC_TYPE_VIDEO:
1219 is->video_st = NULL;
1220 is->video_stream = -1;
1222 case CODEC_TYPE_SUBTITLE:
1223 is->subtitle_st = NULL;
1224 is->subtitle_stream = -1;
1232 dump_stream_info(const AVFormatContext *s)
1235 fprintf(stderr, "Track: %d\n", s->track);
1236 if (s->title[0] != '\0')
1237 fprintf(stderr, "Title: %s\n", s->title);
1238 if (s->author[0] != '\0')
1239 fprintf(stderr, "Author: %s\n", s->author);
1240 if (s->copyright[0] != '\0')
1241 fprintf(stderr, "Copyright: %s\n", s->copyright);
1242 if (s->comment[0] != '\0')
1243 fprintf(stderr, "Comment: %s\n", s->comment);
1244 if (s->album[0] != '\0')
1245 fprintf(stderr, "Album: %s\n", s->album);
1247 fprintf(stderr, "Year: %d\n", s->year);
1248 if (s->genre[0] != '\0')
1249 fprintf(stderr, "Genre: %s\n", s->genre);
1253 AV_SYNC_AUDIO_MASTER, /* default choice */
1254 AV_SYNC_VIDEO_MASTER,
1255 AV_SYNC_EXTERNAL_CLOCK, /* synchronize to an external clock */
1259 stream_open(char *filename, size_t filelen)
1261 VideoState *is = xnew(VideoState);
1262 AVFormatParameters params, *ap = ¶ms;
1265 is->filename = filename;
1266 is->filelen = filelen;
1267 is->iformat = av_find_input_format("fmt");
1271 /* initialise some semaphores */
1272 SXE_SEMAPH_INIT(&is->pictq_sem);
1273 SXE_SEMAPH_INIT(&is->subpq_sem);
1275 is->av_sync_type = AV_SYNC_AUDIO_MASTER;
1276 is->parse_tid = 0; /* SDL_CreateThread(decode_thread, is); */
1278 memset(ap, 0, sizeof(*ap));
1279 /* we force a pause when starting an RTSP stream */
1280 ap->initial_pause = 1;
1282 ap->width = 0; /* frame_width; */
1283 ap->height= 0; /* frame_height; */
1284 ap->time_base= (AVRational){1, 25};
1285 ap->pix_fmt = PIX_FMT_NONE; /* frame_pix_fmt; */
1287 err = av_open_input_file(&is->ic, is->filename, is->iformat, 0, ap);
1288 if (UNLIKELY(err < 0)) {
1289 FFMPEG_DEBUG_AVF("Could not open \"%s\" (errno %d)\n",
1301 /* main analysis function */
1302 static ms_driver_data_t
1303 new_media_ffmpeg_open(Lisp_Media_Stream *ms)
1305 /* the final result */
1306 VideoState *vs = NULL;
1307 int err = 0, use_play = 0;
1308 int wanted_audio_stream = 0;
1309 int wanted_video_stream = 0;
1310 int video_index = -1, audio_index = -1;
1311 mkind_file_properties *mkfp = NULL;
1318 if (media_stream_kind(ms) != MKIND_FILE) {
1323 mkfp = media_stream_kind_properties(ms).fprops;
1324 TO_EXTERNAL_FORMAT(LISP_STRING, mkfp->filename,
1325 MALLOC, (file, file_len), Qnil);
1326 if (UNLIKELY((vs = stream_open(file, file_len)) == NULL)) {
1327 media_stream_set_meths(ms, NULL);
1328 media_stream_driver(ms) = MDRIVER_UNKNOWN;
1332 #ifdef CONFIG_RTSP_DEMUXER
1333 use_play = (ic->iformat == &rtsp_demuxer);
1338 if (1 /* genpts */) {
1339 vs->ic->flags |= AVFMT_FLAG_GENPTS;
1343 err = av_find_stream_info(vs->ic);
1345 FFMPEG_DEBUG_AVF("\"%s\": "
1346 "could not find codec parameters\n",
1351 * ffplay maybe should not use url_feof() to test for the end */
1352 #if defined FFMPEG_URL_FOPEN_BIOCTX_STAR_STAR
1353 vs->ic->pb->eof_reached = 0;
1354 #elif defined FFMPEG_URL_FOPEN_BIOCTX_STAR
1355 vs->ic->pb.eof_reached = 0;
1359 /* now we can begin to play (RTSP stream only) */
1360 av_read_play(vs->ic);
1363 err = av_find_stream_info(vs->ic);
1365 FFMPEG_DEBUG_AVF("\"%s\": "
1366 "could not find codec parameters\n",
1372 for (size_t i = 0; i < vs->ic->nb_streams; i++) {
1373 AVCodecContext *enc = vs->ic->streams[i]->codec;
1374 switch ((unsigned int)enc->codec_type) {
1375 case CODEC_TYPE_AUDIO:
1376 if ((audio_index < 0 || wanted_audio_stream-- > 0)) {
1380 case CODEC_TYPE_VIDEO:
1381 if ((video_index < 0 || wanted_video_stream-- > 0)) {
1389 if (1 /* show_status */) {
1390 dump_format(vs->ic, 0, vs->filename, 0);
1391 dump_stream_info(vs->ic);
1394 /* open the streams */
1395 if (audio_index >= 0) {
1396 stream_component_open(vs, audio_index, ms);
1399 if (video_index >= 0) {
1400 stream_component_open(vs, video_index, ms);
1405 if (vs->video_stream < 0 && vs->audio_stream < 0) {
1406 FFMPEG_DEBUG_AVF("\"%s\": could not open codecs\n",
1411 /* keep the context */
1412 media_stream_data(ms) = vs;
1413 /* set me as driver indicator */
1414 media_stream_driver(ms) = MYSELF;
1424 new_media_ffmpeg_read(media_substream *mss, void *outbuf, size_t length)
1426 VideoState *is = media_stream_data(mss->up); /* was arg */
1428 AVPacket pkt1, *pkt = &pkt1;
1430 /* stuff normally set on the command line */
1431 int64_t start_time = AV_NOPTS_VALUE;
1433 av_init_packet(&flush_pkt);
1434 FFMPEG_CRITICAL("read\n");
1437 /* if seeking requested, we execute it */
1438 if (start_time != AV_NOPTS_VALUE) {
1441 timestamp = start_time;
1442 /* add the stream start time */
1443 if (ic->start_time != AV_NOPTS_VALUE)
1444 timestamp += ic->start_time;
1445 ret = av_seek_frame(ic, -1, timestamp, AVSEEK_FLAG_BACKWARD);
1447 fprintf(stderr, "%s: could not seek to position %0.3f\n",
1448 is->filename, (double)timestamp / AV_TIME_BASE);
1454 if (is->abort_request) {
1455 FFMPEG_DEBUG_AVF("\n");
1458 if (is->paused != is->last_paused) {
1459 is->last_paused = is->paused;
1461 av_read_pause(is->ic);
1463 av_read_play(is->ic);
1465 #ifdef CONFIG_RTSP_DEMUXER
1466 if (is->paused && is->ic->iformat == &rtsp_demuxer) {
1467 /* wait 10 ms to avoid trying to get another packet */
1474 int stream_index= -1;
1475 int64_t seek_target= is->seek_pos;
1477 if (is->video_stream >= 0)
1478 stream_index = is->video_stream;
1479 else if (is->audio_stream >= 0)
1480 stream_index = is->audio_stream;
1481 else if (is->subtitle_stream >= 0)
1482 stream_index = is->subtitle_stream;
1484 if (stream_index >= 0) {
1485 seek_target = av_rescale_q(
1486 seek_target, AV_TIME_BASE_Q,
1487 is->ic->streams[stream_index]->
1491 ret = av_seek_frame(is->ic, stream_index,
1492 seek_target, is->seek_flags);
1494 FFMPEG_DEBUG_AVS("\"%s: \""
1495 "error while seeking\n",
1498 if (is->audio_stream >= 0) {
1499 packet_queue_flush(&is->audioq);
1500 packet_queue_put(&is->audioq, &flush_pkt);
1502 if (is->subtitle_stream >= 0) {
1503 packet_queue_flush(&is->subtitleq);
1504 packet_queue_put(&is->subtitleq, &flush_pkt);
1506 if (is->video_stream >= 0) {
1507 packet_queue_flush(&is->videoq);
1508 packet_queue_put(&is->videoq, &flush_pkt);
1514 /* if the queue are full, no need to read more */
1515 if (is->audioq.size > MAX_AUDIOQ_SIZE ||
1516 is->videoq.size > MAX_VIDEOQ_SIZE ||
1517 is->subtitleq.size > MAX_SUBTITLEQ_SIZE ||
1518 #if defined FFMPEG_URL_FOPEN_BIOCTX_STAR_STAR
1519 url_feof(is->ic->pb)
1520 #elif defined FFMPEG_URL_FOPEN_BIOCTX_STAR
1521 url_feof(&is->ic->pb)
1528 ret = av_read_frame(is->ic, pkt);
1531 #if defined FFMPEG_URL_FOPEN_BIOCTX_STAR_STAR
1533 #elif defined FFMPEG_URL_FOPEN_BIOCTX_STAR
1537 usleep(100); /* wait for user event */
1542 if (pkt->stream_index == is->audio_stream) {
1543 packet_queue_put(&is->audioq, pkt);
1544 } else if (pkt->stream_index == is->video_stream) {
1545 packet_queue_put(&is->videoq, pkt);
1546 } else if (pkt->stream_index == is->subtitle_stream) {
1547 packet_queue_put(&is->subtitleq, pkt);
1549 av_free_packet(pkt);
1552 /* wait until the end */
1553 while (!is->abort_request) {
1558 /* disable interrupting */
1559 global_video_state = NULL;
1561 /* close each stream */
1562 if (is->audio_stream >= 0)
1563 stream_component_close(is, is->audio_stream);
1564 if (is->video_stream >= 0)
1565 stream_component_close(is, is->video_stream);
1566 if (is->subtitle_stream >= 0)
1567 stream_component_close(is, is->subtitle_stream);
1569 av_close_input_file(is->ic);
1570 is->ic = NULL; /* safety */
1572 url_set_interrupt_cb(NULL);
1578 event.type = FF_QUIT_EVENT;
1579 event.user.data1 = is;
1580 SDL_PushEvent(&event);
1587 new_media_ffmpeg_rewind(media_substream *mss)
1589 /* rewind the stream to the first frame */
1591 AVFormatContext *avfc;
1593 Lisp_Media_Stream *ms = mss->up;
1598 /* check the integrity of the media stream */
1599 if (media_stream_driver(ms) != MYSELF)
1602 FFMPEG_DEBUG_AVF("rewind substream 0x%lx\n",
1603 (long unsigned int)mss);
1605 /* fetch the format context */
1606 if (!(avfc = media_stream_data(ms)))
1609 si = (long int)mss->substream_data;
1610 avst = avfc->streams[si];
1611 if ((start_time = avst->start_time) < 0) {
1615 FFMPEG_DEBUG_AVF("rewind (idx:%ld) to %lld\n",
1616 si, (long long int)start_time);
1618 /* ... and reset the stream */
1619 res = av_seek_frame(avfc, -1, start_time, AVSEEK_FLAG_BACKWARD);
1622 FFMPEG_DEBUG_AVF("rewind succeeded\n");
1625 FFMPEG_DEBUG_AVF("rewind exitted with %d\n", res);
1632 media_ffmpeg_available_formats(void)
1634 Lisp_Object formats;
1635 AVInputFormat *avif;
1640 avif = first_iformat;
1644 const Lisp_Object fmtname =
1645 Fintern(build_string(avif->name), Qnil);
1646 formats = Fcons(fmtname, formats);