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);
90 #ifndef AVCODEC_MAX_AUDIO_FRAME_SIZE
91 #define AVCODEC_MAX_AUDIO_FRAME_SIZE 19200
95 media_ffmpeg_bitrate(AVCodecContext *enc)
99 /* for PCM codecs, compute bitrate directly */
100 switch ((unsigned int)enc->codec_id) {
101 case CODEC_ID_PCM_S32LE:
102 case CODEC_ID_PCM_S32BE:
103 case CODEC_ID_PCM_U32LE:
104 case CODEC_ID_PCM_U32BE:
105 bitrate = enc->sample_rate * enc->channels * 32;
107 case CODEC_ID_PCM_S24LE:
108 case CODEC_ID_PCM_S24BE:
109 case CODEC_ID_PCM_U24LE:
110 case CODEC_ID_PCM_U24BE:
111 case CODEC_ID_PCM_S24DAUD:
112 bitrate = enc->sample_rate * enc->channels * 24;
114 case CODEC_ID_PCM_S16LE:
115 case CODEC_ID_PCM_S16BE:
116 case CODEC_ID_PCM_U16LE:
117 case CODEC_ID_PCM_U16BE:
118 bitrate = enc->sample_rate * enc->channels * 16;
120 case CODEC_ID_PCM_S8:
121 case CODEC_ID_PCM_U8:
122 case CODEC_ID_PCM_ALAW:
123 case CODEC_ID_PCM_MULAW:
124 bitrate = enc->sample_rate * enc->channels * 8;
127 bitrate = enc->bit_rate;
133 char *media_ffmpeg_streaminfo(Lisp_Media_Stream *ms)
135 AVFormatContext *avfc = NULL;
136 AVDictionaryEntry *curr = NULL;
138 int chars_left = 4095;
140 avfc = media_stream_data(ms);
141 out = xmalloc_atomic(chars_left+1);
146 out[chars_left] = '\0';
148 /* cannot use ffmpeg on corrupt streams */
149 if (media_stream_driver(ms) != MYSELF || avfc == NULL)
152 if (! avfc->metadata)
156 static const char *keys[] = { "author", "title", "date" };
157 static const size_t nkeys = sizeof(keys)/sizeof(keys[0]);
160 for (i = 0; i < nkeys; ++i ) {
161 curr = av_dict_get(avfc->metadata,
164 AV_DICT_IGNORE_SUFFIX);
168 strncat(out, " :", chars_left);
173 strncat(out, curr->key, chars_left);
174 chars_left -= strlen(curr->key);
178 strncat(out, " \"", chars_left);
183 strncat(out, curr->value, chars_left);
184 chars_left -= strlen(curr->value);
188 strncat(out, "\"", chars_left);
199 media_ffmpeg_print(Lisp_Object ms, Lisp_Object pcfun, int ef)
204 static AVFormatContext*
205 media_ffmpeg_open_file(const char *file)
207 AVFormatContext *avfc = NULL;
210 if (avformat_open_input(&avfc, file, NULL, NULL) < 0) {
211 FFMPEG_DEBUG_AVF("opening file failed.\n");
215 /* Retrieve stream information */
216 if (avformat_find_stream_info(avfc, NULL) < 0) {
217 FFMPEG_DEBUG_AVS("opening stream inside file failed.\n");
218 avformat_close_input(&avfc);
227 media_ffmpeg_vio_read(void *h, unsigned char *buf, int size)
229 media_data *sd = (media_data*)h;
231 FFMPEG_DEBUG_AVS("reading %d bytes to 0x%x, respecting seek %ld\n",
232 size, (unsigned int)buf, sd->seek);
234 if ((long int)sd->length <= sd->seek) {
235 FFMPEG_DEBUG_AVS("eof\n");
239 memcpy(buf, sd->data+sd->seek, size);
246 media_ffmpeg_vio_seek(void *h, int64_t pos, int whence)
248 media_data *sd = (media_data*)h;
250 FFMPEG_DEBUG_AVS("seeking to %ld via %d\n", (long int)pos, whence);
257 sd->seek = sd->seek+pos;
260 sd->seek = sd->length+pos;
269 /** Size of probe buffer, for guessing file type from file contents. */
270 #define PROBE_BUF_MIN 2048
271 #define PROBE_BUF_MAX 131072
274 media_ffmpeg_open_data(char *data, size_t size)
276 AVFormatContext *avfc = NULL;
277 AVIOContext *avio = NULL;
278 media_data *sd = NULL;
279 unsigned char *buffer = NULL;
280 static const int bufsize = 65536;
282 /* initialise our media_data. Note that we need to use
283 * ffmpeg's malloc because it will free it on cleaning of the
284 * context and we don't want allocators corrupting each other.
286 sd = av_malloc(sizeof(media_data));
294 /* allocate the buffer */
295 buffer = av_malloc(bufsize);
299 /* create ffmpeg avio context. Note that at this point thea
300 * AVIOContext has lifetime control of the previously
301 * allocated sd and buffer.
303 avio = avio_alloc_context(buffer,
307 media_ffmpeg_vio_read,
309 media_ffmpeg_vio_seek);
311 /* create format context, and make it use the avio above.
312 Note that at this point avfc has lifetime control of avio,
313 through avformat_free_context */
314 avfc = avformat_alloc_context();
316 avfc->flags = AVFMT_FLAG_CUSTOM_IO;
319 if (avformat_open_input(&avfc, NULL, NULL, NULL) < 0) {
320 FFMPEG_DEBUG_AVF("opening file failed.\n");
321 /* Abundance of caution, as on failure open input
322 should clear the context, but when it does it also
323 sets avfc to NULL so this is safe. */
324 avformat_free_context(avfc);
328 /* Retrieve stream information */
329 if (avformat_find_stream_info(avfc,NULL) < 0) {
330 avformat_close_input(&avfc);
338 media_ffmpeg_close(ms_driver_data_t data)
340 AVFormatContext *avfc = (AVFormatContext*)data;
341 FFMPEG_DEBUG_AVF("closing AVFormatContext: 0x%lx\n",
342 (long unsigned int)avfc);
343 if (avfc && avfc->iformat)
344 avformat_close_input(&avfc);
348 media_ffmpeg_analyse_audio(media_substream *mss, AVFormatContext *avfc, int st)
350 mtype_audio_properties *mtap;
351 const char *name = NULL;
352 const char *codec_name = NULL;
353 /* libavformat cruft */
354 AVStream *avst = NULL;
355 AVCodecContext *avcc = NULL;
357 /* unpack the stream and codec context from the container, again */
359 avst = avfc->streams[st];
364 mtap = xnew_and_zero(mtype_audio_properties);
367 if (avfc && avfc->iformat)
368 name = avfc->iformat->name;
369 if (avcc && avcc->codec)
370 codec_name = avcc->codec->name;
373 mtap->codec_name = codec_name;
375 mtap->channels = avcc->channels;
376 mtap->samplerate = avcc->sample_rate;
377 mtap->bitrate = media_ffmpeg_bitrate(avcc);
380 av_get_bytes_per_sample(avcc->sample_fmt);
381 mtap->samplewidth = 8 * sample_bytes;
382 mtap->framesize = mtap->channels * sample_bytes;
383 /* samplewidth and framesize */
384 switch (avcc->sample_fmt) {
385 case AV_SAMPLE_FMT_U8:
386 assert(sample_bytes == 1);
387 mtap->msf = sxe_msf_U8;
389 case AV_SAMPLE_FMT_S16:
390 assert(sample_bytes == 2);
391 mtap->msf = sxe_msf_S16;
393 case AV_SAMPLE_FMT_S32:
394 assert(sample_bytes == 4);
395 mtap->msf = sxe_msf_S32;
397 case AV_SAMPLE_FMT_FLT:
398 assert(sample_bytes == sizeof(float));
399 mtap->msf = sxe_msf_FLT;
401 case AV_SAMPLE_FMT_DBL:
402 assert(sample_bytes == sizeof(double));
403 mtap->msf = sxe_msf_DBL;
405 case AV_SAMPLE_FMT_NONE:
406 mtap->samplewidth = 0;
411 error(("Unsupported sample format: "
412 "%s (%d), %d bytes/sample"),
413 av_get_sample_fmt_string(
422 mtap->endianness = 0;
425 media_substream_type_properties(mss).aprops = mtap;
426 media_substream_data(mss) = (void*)st;
430 media_ffmpeg_analyse_video(media_substream *mss, AVFormatContext *avfc, int st)
432 mtype_video_properties *mtvp;
433 const char *name = NULL;
434 const char *codec_name = NULL;
435 /* libavformat cruft */
436 AVStream *avst = NULL;
437 AVCodecContext *avcc = NULL;
439 /* unpack the stream and codec context from the container, again */
441 avst = avfc->streams[st];
446 mtvp = xnew_and_zero(mtype_video_properties);
449 if (avfc && avfc->iformat)
450 name = avfc->iformat->name;
451 if (avcc && avcc->codec)
452 codec_name = avcc->codec->name;
455 mtvp->codec_name = codec_name;
457 mtvp->bitrate = avcc->bit_rate;
458 mtvp->width = avcc->width;
459 mtvp->height = avcc->height;
460 mtvp->aspect_num = avcc->sample_aspect_ratio.num;
461 mtvp->aspect_den = avcc->sample_aspect_ratio.den;
464 mtvp->endianness = 0;
467 media_substream_type_properties(mss).vprops = mtvp;
468 media_substream_data(mss) = (void*)st;
471 /* main analysis function */
472 static ms_driver_data_t
473 media_ffmpeg_open(Lisp_Media_Stream *ms)
476 media_substream *mss;
477 /* libavformat stuff */
478 AVFormatContext *avfc = NULL;
479 AVStream *avst = NULL;
480 AVCodecContext *avcc = NULL;
486 switch (media_stream_kind(ms)) {
488 mkind_file_properties *mkfp = NULL;
493 mkfp = media_stream_kind_properties(ms).fprops;
494 TO_EXTERNAL_FORMAT(LISP_STRING, mkfp->filename,
495 ALLOCA, (file, file_len), Qnil);
496 SXE_SET_UNUSED(file_len);
498 avfc = media_ffmpeg_open_file(file);
500 media_stream_set_meths(ms, NULL);
501 media_stream_driver(ms) = MDRIVER_UNKNOWN;
505 /* store the filesize */
506 mkfp->filesize = avio_size(avfc->pb);
510 mkind_string_properties *mksp = NULL;
515 mksp = media_stream_kind_properties(ms).sprops;
516 data = mksp->stream_data;
518 avfc = media_ffmpeg_open_data(data, size);
521 media_stream_set_meths(ms, NULL);
522 media_stream_driver(ms) = MDRIVER_UNKNOWN;
530 case NUMBER_OF_MEDIA_KINDS:
536 /* check if there is at least one usable stream */
537 for (size_t st = 0; st < avfc->nb_streams; st++) {
538 avst = avfc->streams[st];
541 avcc->codec_id != CODEC_ID_NONE &&
542 avcc->codec_type != AVMEDIA_TYPE_DATA &&
543 (avc = avcodec_find_decoder(avcc->codec_id)) &&
544 (avc && (avcodec_open2(avcc, avc, NULL) >= 0))) {
546 /* create a substream */
547 mss = make_media_substream_append(ms);
549 switch ((unsigned int)avcc->codec_type) {
550 case AVMEDIA_TYPE_VIDEO:
551 /* assign substream props */
552 media_substream_type(mss) = MTYPE_VIDEO;
553 media_ffmpeg_analyse_video(mss, avfc, st);
555 case AVMEDIA_TYPE_AUDIO:
556 /* assign substream props */
557 media_substream_type(mss) = MTYPE_AUDIO;
558 media_ffmpeg_analyse_audio(mss, avfc, st);
559 /* set some stream handlers */
560 media_stream_set_meths(ms, media_ffmpeg);
562 case AVMEDIA_TYPE_DATA:
563 media_substream_type(mss) = MTYPE_IMAGE;
566 media_substream_type(mss) = MTYPE_UNKNOWN;
572 /* keep the format context */
573 media_stream_data(ms) = avfc;
575 /* set me as driver indicator */
576 media_stream_driver(ms) = MYSELF;
583 handle_packet(AVFormatContext *avfc, AVPacket *pkt)
588 int ret, got_picture;
590 st = avfc->streams[pkt->stream_index];
592 /* XXX: allocate picture correctly */
593 avcodec_get_frame_defaults(&picture);
595 ret = avcodec_decode_video(
596 st->codec, &picture, &got_picture, pkt->data, pkt->size);
604 FFMPEG_DEBUG_AVF("got video frame\n");
614 media_ffmpeg_read(media_substream *mss, void *outbuf, size_t length)
616 /* read at most `length' frames into `outbuf' */
617 /* convert them to internal format */
619 Lisp_Media_Stream *ms = mss->up;
620 mtype_audio_properties *mtap;
621 media_sample_format_t *fmt;
623 AVFormatContext *avfc;
625 AVCodecContext *avcc;
629 /* the size we present here, is _not_ the size we want, however
630 * ffmpeg is quite pedantic about the buffer size,
631 * we just pass the least possible value here to please him */
632 int size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
635 long int bufseek = 0, si = -1;
636 int declen, dec, rf_status = 0;
638 /* check the integrity of the media stream */
639 if (media_stream_driver(ms) != MYSELF)
642 /* fetch the format context */
643 avfc = media_stream_data(ms);
648 si = (long int)mss->substream_data;
649 avst = avfc->streams[si];
654 /* unpack the substream */
655 if ((mtap = media_substream_type_properties(mss).aprops) == NULL) {
656 FFMPEG_DEBUG_AVS("stream information missing. Uh Oh.\n");
660 /* fetch audio info */
661 framesize = mtap->framesize;
664 /* initialise the packet */
665 pkt.pts = pkt.dts = pkt.size = 0;
666 FFMPEG_DEBUG_AVF("initialised packet: "
667 "pts:%lld dts:%lld psz:%d\n",
668 (long long int)pkt.pts,
669 (long long int)pkt.dts,
672 /* read a frame and decode it */
673 while ((size_t)bufseek <= length*framesize &&
674 (rf_status = av_read_frame(avfc, &pkt)) >= 0) {
675 if (pkt.stream_index != si) {
676 FFMPEG_DEBUG_AVF("SKIP reason: "
677 "sought after stream %ld, got %ld\n",
679 (long int)pkt.stream_index);
680 handle_packet(avfc, &pkt);
684 FFMPEG_DEBUG_AVF("read frame: "
685 "pts:%lld dts:%lld psz:%d\n",
686 (long long int)pkt.pts,
687 (long long int)pkt.dts,
691 /* decode the demuxed packet */
692 #ifdef HAVE_AVCODEC_DECODE_AUDIO3
693 /* prefer decode_audio3() if available */
694 size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
695 declen = avcodec_decode_audio3(
696 avcc, (void*)((char*)outbuf+bufseek),
698 #elif HAVE_AVCODEC_DECODE_AUDIO2
699 /* prefer decode_audio2() if available */
700 size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
701 declen = avcodec_decode_audio2(
702 avcc, (void*)((char*)outbuf+bufseek),
703 &size, pkt.data, pkt.size);
704 #elif defined HAVE_AVCODEC_DECODE_AUDIO
705 declen = avcodec_decode_audio(
706 avcc, (void*)((char*)outbuf+bufseek),
707 &size, pkt.data, pkt.size);
712 if (dec > 0 && size > 0) {
713 FFMPEG_DEBUG_AVF("pts:%lld dts:%lld psz:%d s:%d d:%d\n",
714 (long long int)pkt.pts,
715 (long long int)pkt.dts,
716 pkt.size, size, declen);
717 /* Because FFMPEG_DEBUG_AVF may expand to nothing ... */
718 SXE_SET_UNUSED(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 */
909 /* packet queue handling */
911 packet_queue_init(PacketQueue *q)
913 memset(q, 0, sizeof(PacketQueue));
914 SXE_SEMAPH_INIT(&q->sem);
918 packet_queue_flush(PacketQueue *q)
920 AVPacketList *pkt, *pkt1;
922 SXE_SEMAPH_LOCK(&q->sem);
923 for (pkt = q->first_pkt; pkt != NULL; pkt = pkt1) {
925 av_free_packet(&pkt->pkt);
932 SXE_SEMAPH_UNLOCK(&q->sem);
936 packet_queue_end(PacketQueue *q)
938 packet_queue_flush(q);
939 SXE_SEMAPH_FINI(&q->sem);
943 packet_queue_put(PacketQueue *q, AVPacket *pkt)
947 /* duplicate the packet */
948 if (pkt!=&flush_pkt && av_dup_packet(pkt) < 0)
951 pkt1 = av_malloc(sizeof(AVPacketList));
958 SXE_SEMAPH_LOCK(&q->sem);
964 q->last_pkt->next = pkt1;
967 q->size += pkt1->pkt.size;
968 /* XXX: should duplicate packet data in DV case */
969 SXE_SEMAPH_SIGNAL(&q->sem);
970 SXE_SEMAPH_UNLOCK(&q->sem);
975 packet_queue_abort(PacketQueue *q)
977 SXE_SEMAPH_LOCK(&q->sem);
979 q->abort_request = 1;
981 SXE_SEMAPH_SIGNAL(&q->sem);
982 SXE_SEMAPH_UNLOCK(&q->sem);
985 /* return < 0 if aborted, 0 if no packet and > 0 if packet. */
987 packet_queue_get(PacketQueue *q, AVPacket *pkt, int block)
988 __attribute__((unused));
991 packet_queue_get(PacketQueue *q, AVPacket *pkt, int block)
996 SXE_SEMAPH_LOCK(&q->sem);
999 if (q->abort_request) {
1004 pkt1 = q->first_pkt;
1006 q->first_pkt = pkt1->next;
1010 q->size -= pkt1->pkt.size;
1015 } else if (!block) {
1019 SXE_SEMAPH_WAIT(&q->sem);
1022 SXE_SEMAPH_UNLOCK(&q->sem);
1026 static uint64_t global_video_pkt_pts = AV_NOPTS_VALUE;
1029 my_get_buffer(struct AVCodecContext *c, AVFrame *pic, int flags)
1031 int ret= avcodec_default_get_buffer2(c, pic, flags);
1032 uint64_t *pts= av_malloc(sizeof(uint64_t));
1033 *pts= global_video_pkt_pts;
1039 stream_component_open(VideoState *is, int stream_index, Lisp_Media_Stream *ms)
1042 media_substream *mss = NULL;
1043 AVFormatContext *ic = is->ic;
1044 AVCodecContext *enc;
1047 if (stream_index < 0 || (size_t)stream_index >= ic->nb_streams) {
1050 enc = ic->streams[stream_index]->codec;
1052 /* prepare audio output */
1053 if (enc->codec_type == AVMEDIA_TYPE_AUDIO) {
1055 wanted_spec.freq = enc->sample_rate;
1056 wanted_spec.format = AUDIO_S16SYS;
1058 /* hack for AC3. XXX: suppress that */
1059 if (enc->channels > 2)
1062 wanted_spec.channels = enc->channels;
1063 wanted_spec.silence = 0;
1064 wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;
1065 wanted_spec.callback = sdl_audio_callback;
1066 wanted_spec.userdata = is;
1068 is->audio_hw_buf_size = 0 /* spec.size */;
1071 codec = avcodec_find_decoder(enc->codec_id);
1072 enc->debug_mv = 0 /* debug_mv */;
1073 enc->debug = 0 /* debug */;
1074 enc->workaround_bugs = 0 /* workaround_bugs */;
1075 enc->lowres = 0 /* lowres */;
1077 enc->flags |= CODEC_FLAG_EMU_EDGE;
1078 enc->idct_algo = FF_IDCT_AUTO; /* idct; */
1080 enc->flags2 |= CODEC_FLAG2_FAST;
1081 enc->skip_frame = AVDISCARD_DEFAULT; /* skip_frame; */
1082 enc->skip_idct = AVDISCARD_DEFAULT; /* skip_idct; */
1083 enc->skip_loop_filter = AVDISCARD_DEFAULT; /* skip_loop_filter; */
1085 enc->error_resilience = FF_ER_CAREFUL; /* error_resilience; */
1087 enc->error_concealment = 3; /* error_concealment; */
1088 if (1 /* thread_count */ > 1)
1089 enc->thread_count = 1 /* thread_count */;
1092 avcodec_open2(enc, codec, NULL) < 0)
1095 /* create a substream */
1096 mss = make_media_substream_append(ms);
1098 switch ((unsigned int)enc->codec_type) {
1099 case AVMEDIA_TYPE_AUDIO:
1100 is->audio_stream = stream_index;
1101 is->audio_st = ic->streams[stream_index];
1102 is->audio_buf_size = 0;
1103 is->audio_buf_index = 0;
1105 /* init averaging filter */
1106 is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
1107 is->audio_diff_avg_count = 0;
1108 /* since we do not have a precise anough audio fifo fullness,
1109 we correct audio sync only if larger than this threshold */
1110 is->audio_diff_threshold =
1111 2.0 * SDL_AUDIO_BUFFER_SIZE / enc->sample_rate;
1113 memset(&is->audio_pkt, 0, sizeof(is->audio_pkt));
1114 packet_queue_init(&is->audioq);
1116 media_substream_type(mss) = MTYPE_AUDIO;
1117 media_ffmpeg_analyse_audio(mss, is->ic, stream_index);
1119 case AVMEDIA_TYPE_VIDEO:
1120 is->video_stream = stream_index;
1121 is->video_st = ic->streams[stream_index];
1123 is->frame_last_delay = 40e-3;
1125 int64_t tmp = av_gettime();
1126 is->frame_timer = (double)tmp / 1000000.0f;
1128 is->video_current_pts_time = av_gettime();
1130 packet_queue_init(&is->videoq);
1131 is->video_tid = 0 /* SDL_CreateThread(video_thread, is) */;
1133 enc->get_buffer2 = my_get_buffer;
1134 media_substream_type(mss) = MTYPE_VIDEO;
1136 media_ffmpeg_analyse_video(mss, is->ic, stream_index);
1138 case AVMEDIA_TYPE_SUBTITLE:
1139 is->subtitle_stream = stream_index;
1140 is->subtitle_st = ic->streams[stream_index];
1141 packet_queue_init(&is->subtitleq);
1143 is->subtitle_tid = 0 /*SDL_CreateThread(subtitle_thread, is)*/;
1152 stream_component_close(VideoState *is, int stream_index)
1154 AVFormatContext *ic = is->ic;
1155 AVCodecContext *enc;
1157 if (stream_index < 0 || (size_t)stream_index >= ic->nb_streams) {
1160 enc = ic->streams[stream_index]->codec;
1162 switch ((unsigned int)enc->codec_type) {
1163 case AVMEDIA_TYPE_AUDIO:
1164 packet_queue_abort(&is->audioq);
1168 packet_queue_end(&is->audioq);
1170 case AVMEDIA_TYPE_VIDEO:
1171 packet_queue_abort(&is->videoq);
1173 /* note: we also signal this mutex to make sure we deblock the
1174 video thread in all cases */
1175 SXE_SEMAPH_LOCK(&is->pictq_sem);
1176 SXE_SEMAPH_SIGNAL(&is->pictq_sem);
1177 SXE_SEMAPH_UNLOCK(&is->pictq_sem);
1179 SDL_WaitThread(is->video_tid, NULL);
1181 packet_queue_end(&is->videoq);
1183 case AVMEDIA_TYPE_SUBTITLE:
1184 packet_queue_abort(&is->subtitleq);
1186 /* note: we also signal this mutex to make sure we deblock the
1187 video thread in all cases */
1188 SXE_SEMAPH_LOCK(&is->subpq_sem);
1189 is->subtitle_stream_changed = 1;
1191 SXE_SEMAPH_SIGNAL(&is->subpq_sem);
1192 SXE_SEMAPH_UNLOCK(&is->subpq_sem);
1194 SDL_WaitThread(is->subtitle_tid, NULL);
1196 packet_queue_end(&is->subtitleq);
1203 switch ((unsigned int)enc->codec_type) {
1204 case AVMEDIA_TYPE_AUDIO:
1205 is->audio_st = NULL;
1206 is->audio_stream = -1;
1208 case AVMEDIA_TYPE_VIDEO:
1209 is->video_st = NULL;
1210 is->video_stream = -1;
1212 case AVMEDIA_TYPE_SUBTITLE:
1213 is->subtitle_st = NULL;
1214 is->subtitle_stream = -1;
1222 dump_stream_info(const AVFormatContext *s)
1224 static const char *keys[] = {
1225 "track", "title", "author", "copyright", "comment",
1226 "album", "date", "genre"
1228 static const size_t nkeys = sizeof(keys)/sizeof(keys[0]);
1230 AVDictionaryEntry *curr = NULL;
1231 if (! s->metadata) {
1232 fprintf(stderr, "No metadata\n");
1236 for (i = 0; i < nkeys; ++i ) {
1237 curr = av_dict_get(s->metadata,
1240 AV_DICT_IGNORE_SUFFIX);
1242 fprintf(stderr, "%s: %s\n", curr->key, curr->value);
1247 AV_SYNC_AUDIO_MASTER, /* default choice */
1248 AV_SYNC_VIDEO_MASTER,
1249 AV_SYNC_EXTERNAL_CLOCK, /* synchronize to an external clock */
1253 stream_open(char *filename, size_t filelen)
1255 VideoState *is = xnew(VideoState);
1256 AVDictionary *options = NULL;
1259 is->filename = filename;
1260 is->filelen = filelen;
1261 is->iformat = av_find_input_format("fmt");
1265 /* initialise some semaphores */
1266 SXE_SEMAPH_INIT(&is->pictq_sem);
1267 SXE_SEMAPH_INIT(&is->subpq_sem);
1269 is->av_sync_type = AV_SYNC_AUDIO_MASTER;
1270 is->parse_tid = 0; /* SDL_CreateThread(decode_thread, is); */
1273 /* we force a pause when starting an RTSP stream */
1274 ap->initial_pause = 1;
1276 ap->width = 0; /* frame_width; */
1277 ap->height= 0; /* frame_height; */
1278 ap->time_base= (AVRational){1, 25};
1279 ap->pix_fmt = PIX_FMT_NONE; /* frame_pix_fmt; */
1282 err = avformat_open_input(&is->ic, is->filename, is->iformat, &options);
1283 if (UNLIKELY(err < 0)) {
1284 FFMPEG_DEBUG_AVF("Could not open \"%s\" (errno %d)\n",
1296 /* main analysis function */
1297 static ms_driver_data_t
1298 new_media_ffmpeg_open(Lisp_Media_Stream *ms)
1300 /* the final result */
1301 VideoState *vs = NULL;
1302 int err = 0, use_play = 0;
1303 int wanted_audio_stream = 0;
1304 int wanted_video_stream = 0;
1305 int video_index = -1, audio_index = -1;
1306 mkind_file_properties *mkfp = NULL;
1313 if (media_stream_kind(ms) != MKIND_FILE) {
1318 mkfp = media_stream_kind_properties(ms).fprops;
1319 TO_EXTERNAL_FORMAT(LISP_STRING, mkfp->filename,
1320 MALLOC, (file, file_len), Qnil);
1321 if (UNLIKELY((vs = stream_open(file, file_len)) == NULL)) {
1322 media_stream_set_meths(ms, NULL);
1323 media_stream_driver(ms) = MDRIVER_UNKNOWN;
1327 #ifdef CONFIG_RTSP_DEMUXER
1328 use_play = (ic->iformat == &rtsp_demuxer);
1333 if (1 /* genpts */) {
1334 vs->ic->flags |= AVFMT_FLAG_GENPTS;
1338 err = avformat_find_stream_info(vs->ic, NULL);
1340 FFMPEG_DEBUG_AVF("\"%s\": "
1341 "could not find codec parameters\n",
1346 * ffplay maybe should not use url_feof() to test for the end */
1347 vs->ic->pb->eof_reached = 0;
1350 /* now we can begin to play (RTSP stream only) */
1351 av_read_play(vs->ic);
1354 err = avformat_find_stream_info(vs->ic, NULL);
1356 FFMPEG_DEBUG_AVF("\"%s\": "
1357 "could not find codec parameters\n",
1363 for (size_t i = 0; i < vs->ic->nb_streams; i++) {
1364 AVCodecContext *enc = vs->ic->streams[i]->codec;
1365 switch ((unsigned int)enc->codec_type) {
1366 case AVMEDIA_TYPE_AUDIO:
1367 if ((audio_index < 0 || wanted_audio_stream-- > 0)) {
1371 case AVMEDIA_TYPE_VIDEO:
1372 if ((video_index < 0 || wanted_video_stream-- > 0)) {
1380 if (1 /* show_status */) {
1381 av_dump_format(vs->ic, 0, vs->filename, 0);
1382 dump_stream_info(vs->ic);
1385 /* open the streams */
1386 if (audio_index >= 0) {
1387 stream_component_open(vs, audio_index, ms);
1390 if (video_index >= 0) {
1391 stream_component_open(vs, video_index, ms);
1396 if (vs->video_stream < 0 && vs->audio_stream < 0) {
1397 FFMPEG_DEBUG_AVF("\"%s\": could not open codecs\n",
1402 /* keep the context */
1403 media_stream_data(ms) = vs;
1404 /* set me as driver indicator */
1405 media_stream_driver(ms) = MYSELF;
1415 new_media_ffmpeg_read(media_substream *mss, void *outbuf, size_t length)
1417 VideoState *is = media_stream_data(mss->up); /* was arg */
1419 AVPacket pkt1, *pkt = &pkt1;
1421 /* stuff normally set on the command line */
1422 int64_t start_time = AV_NOPTS_VALUE;
1424 av_init_packet(&flush_pkt);
1425 FFMPEG_CRITICAL("read\n");
1428 /* if seeking requested, we execute it */
1429 if (start_time != AV_NOPTS_VALUE) {
1432 timestamp = start_time;
1433 /* add the stream start time */
1434 if (ic->start_time != AV_NOPTS_VALUE)
1435 timestamp += ic->start_time;
1436 ret = av_seek_frame(ic, -1, timestamp, AVSEEK_FLAG_BACKWARD);
1438 fprintf(stderr, "%s: could not seek to position %0.3f\n",
1439 is->filename, (double)timestamp / AV_TIME_BASE);
1445 if (is->abort_request) {
1446 FFMPEG_DEBUG_AVF("\n");
1449 if (is->paused != is->last_paused) {
1450 is->last_paused = is->paused;
1452 av_read_pause(is->ic);
1454 av_read_play(is->ic);
1456 #ifdef CONFIG_RTSP_DEMUXER
1457 if (is->paused && is->ic->iformat == &rtsp_demuxer) {
1458 /* wait 10 ms to avoid trying to get another packet */
1465 int stream_index= -1;
1466 int64_t seek_target= is->seek_pos;
1468 if (is->video_stream >= 0)
1469 stream_index = is->video_stream;
1470 else if (is->audio_stream >= 0)
1471 stream_index = is->audio_stream;
1472 else if (is->subtitle_stream >= 0)
1473 stream_index = is->subtitle_stream;
1475 if (stream_index >= 0) {
1476 seek_target = av_rescale_q(
1477 seek_target, AV_TIME_BASE_Q,
1478 is->ic->streams[stream_index]->
1482 ret = av_seek_frame(is->ic, stream_index,
1483 seek_target, is->seek_flags);
1485 FFMPEG_DEBUG_AVS("\"%s: \""
1486 "error while seeking\n",
1489 if (is->audio_stream >= 0) {
1490 packet_queue_flush(&is->audioq);
1491 packet_queue_put(&is->audioq, &flush_pkt);
1493 if (is->subtitle_stream >= 0) {
1494 packet_queue_flush(&is->subtitleq);
1495 packet_queue_put(&is->subtitleq, &flush_pkt);
1497 if (is->video_stream >= 0) {
1498 packet_queue_flush(&is->videoq);
1499 packet_queue_put(&is->videoq, &flush_pkt);
1505 /* if the queue are full, no need to read more */
1506 if (is->audioq.size > MAX_AUDIOQ_SIZE ||
1507 is->videoq.size > MAX_VIDEOQ_SIZE ||
1508 is->subtitleq.size > MAX_SUBTITLEQ_SIZE ||
1509 avio_feof(is->ic->pb)) {
1514 ret = av_read_frame(is->ic, pkt);
1516 if (is->ic->pb->error == 0) {
1517 usleep(100); /* wait for user event */
1522 if (pkt->stream_index == is->audio_stream) {
1523 packet_queue_put(&is->audioq, pkt);
1524 } else if (pkt->stream_index == is->video_stream) {
1525 packet_queue_put(&is->videoq, pkt);
1526 } else if (pkt->stream_index == is->subtitle_stream) {
1527 packet_queue_put(&is->subtitleq, pkt);
1529 av_free_packet(pkt);
1532 /* wait until the end */
1533 while (!is->abort_request) {
1539 /* close each stream */
1540 if (is->audio_stream >= 0)
1541 stream_component_close(is, is->audio_stream);
1542 if (is->video_stream >= 0)
1543 stream_component_close(is, is->video_stream);
1544 if (is->subtitle_stream >= 0)
1545 stream_component_close(is, is->subtitle_stream);
1547 avformat_close_input(&is->ic);
1548 is->ic = NULL; /* safety */
1552 url_set_interrupt_cb(NULL);
1559 event.type = FF_QUIT_EVENT;
1560 event.user.data1 = is;
1561 SDL_PushEvent(&event);
1568 new_media_ffmpeg_rewind(media_substream *mss)
1570 /* rewind the stream to the first frame */
1572 AVFormatContext *avfc;
1574 Lisp_Media_Stream *ms = mss->up;
1579 /* check the integrity of the media stream */
1580 if (media_stream_driver(ms) != MYSELF)
1583 FFMPEG_DEBUG_AVF("rewind substream 0x%lx\n",
1584 (long unsigned int)mss);
1586 /* fetch the format context */
1587 if (!(avfc = media_stream_data(ms)))
1590 si = (long int)mss->substream_data;
1591 avst = avfc->streams[si];
1592 if ((start_time = avst->start_time) < 0) {
1596 FFMPEG_DEBUG_AVF("rewind (idx:%ld) to %lld\n",
1597 si, (long long int)start_time);
1599 /* ... and reset the stream */
1600 res = av_seek_frame(avfc, -1, start_time, AVSEEK_FLAG_BACKWARD);
1603 FFMPEG_DEBUG_AVF("rewind succeeded\n");
1606 FFMPEG_DEBUG_AVF("rewind exitted with %d\n", res);
1613 media_ffmpeg_available_formats(void)
1615 Lisp_Object formats;
1616 AVInputFormat *avif = NULL;
1621 avif = av_iformat_next(avif);
1625 const Lisp_Object fmtname =
1626 Fintern(build_string(avif->name), Qnil);
1627 formats = Fcons(fmtname, formats);
1629 avif = av_iformat_next(avif);