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);
379 /* samplewidth and framesize */
380 switch (avcc->sample_fmt) {
381 case AV_SAMPLE_FMT_U8:
382 mtap->samplewidth = 8;
383 mtap->framesize = mtap->channels * 1;
384 mtap->msf = sxe_msf_U8;
386 case AV_SAMPLE_FMT_S16:
387 mtap->samplewidth = 16;
388 mtap->framesize = mtap->channels * 2;
389 mtap->msf = sxe_msf_S16;
391 #if defined AV_SAMPLE_FMT_S24
392 case AV_SAMPLE_FMT_S24:
393 mtap->samplewidth = 32;
394 mtap->framesize = mtap->channels * 4;
395 mtap->msf = sxe_msf_S24;
397 #endif /* SAMPLE_FMT_S24 */
398 case AV_SAMPLE_FMT_S32:
399 mtap->samplewidth = 32;
400 mtap->framesize = mtap->channels * 4;
401 mtap->msf = sxe_msf_S32;
403 case AV_SAMPLE_FMT_FLT:
404 mtap->samplewidth = 8*sizeof(float);
405 mtap->framesize = mtap->channels * sizeof(float);
406 mtap->msf = sxe_msf_FLT;
408 case AV_SAMPLE_FMT_NONE:
410 mtap->samplewidth = 0;
414 mtap->endianness = 0;
417 media_substream_type_properties(mss).aprops = mtap;
418 media_substream_data(mss) = (void*)st;
422 media_ffmpeg_analyse_video(media_substream *mss, AVFormatContext *avfc, int st)
424 mtype_video_properties *mtvp;
425 const char *name = NULL;
426 const char *codec_name = NULL;
427 /* libavformat cruft */
428 AVStream *avst = NULL;
429 AVCodecContext *avcc = NULL;
431 /* unpack the stream and codec context from the container, again */
433 avst = avfc->streams[st];
438 mtvp = xnew_and_zero(mtype_video_properties);
441 if (avfc && avfc->iformat)
442 name = avfc->iformat->name;
443 if (avcc && avcc->codec)
444 codec_name = avcc->codec->name;
447 mtvp->codec_name = codec_name;
449 mtvp->bitrate = avcc->bit_rate;
450 mtvp->width = avcc->width;
451 mtvp->height = avcc->height;
452 mtvp->aspect_num = avcc->sample_aspect_ratio.num;
453 mtvp->aspect_den = avcc->sample_aspect_ratio.den;
456 mtvp->endianness = 0;
459 media_substream_type_properties(mss).vprops = mtvp;
460 media_substream_data(mss) = (void*)st;
463 /* main analysis function */
464 static ms_driver_data_t
465 media_ffmpeg_open(Lisp_Media_Stream *ms)
468 media_substream *mss;
469 /* libavformat stuff */
470 AVFormatContext *avfc = NULL;
471 AVStream *avst = NULL;
472 AVCodecContext *avcc = NULL;
478 switch (media_stream_kind(ms)) {
480 mkind_file_properties *mkfp = NULL;
485 mkfp = media_stream_kind_properties(ms).fprops;
486 TO_EXTERNAL_FORMAT(LISP_STRING, mkfp->filename,
487 ALLOCA, (file, file_len), Qnil);
488 SXE_SET_UNUSED(file_len);
490 avfc = media_ffmpeg_open_file(file);
492 media_stream_set_meths(ms, NULL);
493 media_stream_driver(ms) = MDRIVER_UNKNOWN;
497 /* store the filesize */
498 mkfp->filesize = avio_size(avfc->pb);
502 mkind_string_properties *mksp = NULL;
507 mksp = media_stream_kind_properties(ms).sprops;
508 data = mksp->stream_data;
510 avfc = media_ffmpeg_open_data(data, size);
513 media_stream_set_meths(ms, NULL);
514 media_stream_driver(ms) = MDRIVER_UNKNOWN;
522 case NUMBER_OF_MEDIA_KINDS:
528 /* check if there is at least one usable stream */
529 for (size_t st = 0; st < avfc->nb_streams; st++) {
530 avst = avfc->streams[st];
533 avcc->codec_id != CODEC_ID_NONE &&
534 avcc->codec_type != AVMEDIA_TYPE_DATA &&
535 (avc = avcodec_find_decoder(avcc->codec_id)) &&
536 (avc && (avcodec_open2(avcc, avc, NULL) >= 0))) {
538 /* create a substream */
539 mss = make_media_substream_append(ms);
541 switch ((unsigned int)avcc->codec_type) {
542 case AVMEDIA_TYPE_VIDEO:
543 /* assign substream props */
544 media_substream_type(mss) = MTYPE_VIDEO;
545 media_ffmpeg_analyse_video(mss, avfc, st);
547 case AVMEDIA_TYPE_AUDIO:
548 /* assign substream props */
549 media_substream_type(mss) = MTYPE_AUDIO;
550 media_ffmpeg_analyse_audio(mss, avfc, st);
551 /* set some stream handlers */
552 media_stream_set_meths(ms, media_ffmpeg);
554 case AVMEDIA_TYPE_DATA:
555 media_substream_type(mss) = MTYPE_IMAGE;
558 media_substream_type(mss) = MTYPE_UNKNOWN;
564 /* keep the format context */
565 media_stream_data(ms) = avfc;
567 /* set me as driver indicator */
568 media_stream_driver(ms) = MYSELF;
575 handle_packet(AVFormatContext *avfc, AVPacket *pkt)
580 int ret, got_picture;
582 st = avfc->streams[pkt->stream_index];
584 /* XXX: allocate picture correctly */
585 avcodec_get_frame_defaults(&picture);
587 ret = avcodec_decode_video(
588 st->codec, &picture, &got_picture, pkt->data, pkt->size);
596 FFMPEG_DEBUG_AVF("got video frame\n");
606 media_ffmpeg_read(media_substream *mss, void *outbuf, size_t length)
608 /* read at most `length' frames into `outbuf' */
609 /* convert them to internal format */
611 Lisp_Media_Stream *ms = mss->up;
612 mtype_audio_properties *mtap;
613 media_sample_format_t *fmt;
615 AVFormatContext *avfc;
617 AVCodecContext *avcc;
621 /* the size we present here, is _not_ the size we want, however
622 * ffmpeg is quite pedantic about the buffer size,
623 * we just pass the least possible value here to please him */
624 int size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
627 long int bufseek = 0, si = -1;
628 int declen, dec, rf_status = 0;
630 /* check the integrity of the media stream */
631 if (media_stream_driver(ms) != MYSELF)
634 /* fetch the format context */
635 avfc = media_stream_data(ms);
640 si = (long int)mss->substream_data;
641 avst = avfc->streams[si];
646 /* unpack the substream */
647 if ((mtap = media_substream_type_properties(mss).aprops) == NULL) {
648 FFMPEG_DEBUG_AVS("stream information missing. Uh Oh.\n");
652 /* fetch audio info */
653 framesize = mtap->framesize;
656 /* initialise the packet */
657 pkt.pts = pkt.dts = pkt.size = 0;
658 FFMPEG_DEBUG_AVF("initialised packet: "
659 "pts:%lld dts:%lld psz:%d\n",
660 (long long int)pkt.pts,
661 (long long int)pkt.dts,
664 /* read a frame and decode it */
665 while ((size_t)bufseek <= length*framesize &&
666 (rf_status = av_read_frame(avfc, &pkt)) >= 0) {
667 if (pkt.stream_index != si) {
668 FFMPEG_DEBUG_AVF("SKIP reason: "
669 "sought after stream %ld, got %ld\n",
671 (long int)pkt.stream_index);
672 handle_packet(avfc, &pkt);
676 FFMPEG_DEBUG_AVF("read frame: "
677 "pts:%lld dts:%lld psz:%d\n",
678 (long long int)pkt.pts,
679 (long long int)pkt.dts,
683 /* decode the demuxed packet */
684 #ifdef HAVE_AVCODEC_DECODE_AUDIO2
685 /* prefer decode_audio2() if available */
686 size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
687 declen = avcodec_decode_audio2(
688 avcc, (void*)((char*)outbuf+bufseek),
689 &size, pkt.data, pkt.size);
690 #elif defined HAVE_AVCODEC_DECODE_AUDIO
691 declen = avcodec_decode_audio(
692 avcc, (void*)((char*)outbuf+bufseek),
693 &size, pkt.data, pkt.size);
698 if (dec > 0 && size > 0) {
699 FFMPEG_DEBUG_AVF("pts:%lld dts:%lld psz:%d s:%d d:%d\n",
700 (long long int)pkt.pts,
701 (long long int)pkt.dts,
702 pkt.size, size, declen);
703 /* Because FFMPEG_DEBUG_AVF may expand to nothing ... */
704 SXE_SET_UNUSED(declen);
706 /* memcpy(outbuf+bufseek, (char*)buffer, size); */
710 FFMPEG_DEBUG_AVF("packet state: "
711 "pts:%lld dts:%lld psz:%d\n",
712 (long long int)pkt.pts,
713 (long long int)pkt.dts,
715 av_free_packet(&pkt);
717 av_free_packet(&pkt);
719 FFMPEG_DEBUG_AVF("finished reading, bufseek=%ld, rf_status=%ld\n",
720 (long int)bufseek, (long int)rf_status);
722 /* convert the pig */
723 size = bufseek/framesize;
724 MEDIA_SAMPLE_FORMAT_UPSAMPLE(fmt)(outbuf, outbuf, size*mtap->channels);
731 media_ffmpeg_rewind(media_substream *mss)
733 /* rewind the stream to the first frame */
735 AVFormatContext *avfc;
737 Lisp_Media_Stream *ms = mss->up;
742 /* check the integrity of the media stream */
743 if (media_stream_driver(ms) != MYSELF)
746 FFMPEG_DEBUG_AVF("rewind substream 0x%lx\n",
747 (long unsigned int)mss);
749 /* fetch the format context */
750 if (!(avfc = media_stream_data(ms)))
753 si = (long int)mss->substream_data;
754 avst = avfc->streams[si];
755 if ((start_time = avst->start_time) < 0) {
759 FFMPEG_DEBUG_AVF("rewind (idx:%ld) to %lld\n",
760 si, (long long int)start_time);
762 /* ... and reset the stream */
763 res = av_seek_frame(avfc, si, AV_NOPTS_VALUE, AVSEEK_FLAG_BACKWARD);
766 FFMPEG_DEBUG_AVF("rewind succeeded\n");
769 FFMPEG_DEBUG_AVF("rewind exitted with %d\n", res);
776 * the size must be big enough to compensate the hardware audio buffersize size
778 #define SAMPLE_ARRAY_SIZE (2*65536)
779 #define VIDEO_PICTURE_QUEUE_SIZE 1
780 #define SUBPICTURE_QUEUE_SIZE 4
781 #define AUDIO_DIFF_AVG_NB 20
782 #define SDL_AUDIO_BUFFER_SIZE 1024
784 #define MAX_VIDEOQ_SIZE (5 * 256 * 1024)
785 #define MAX_AUDIOQ_SIZE (5 * 16 * 1024)
786 #define MAX_SUBTITLEQ_SIZE (5 * 16 * 1024)
788 #define FF_ALLOC_EVENT 0
789 #define FF_REFRESH_EVENT 1
790 #define FF_QUIT_EVENT 2
792 typedef struct PacketQueue {
793 AVPacketList *first_pkt, *last_pkt;
797 struct sxe_semaphore_s sem;
800 typedef struct VideoPicture {
801 /* presentation time stamp for this picture */
804 int width, height; /* source height & width */
808 typedef struct SubPicture {
809 double pts; /* presentation time stamp for this picture */
813 typedef struct VideoState {
816 AVInputFormat *iformat;
825 int dtg_active_format;
830 double external_clock; /* external clock base */
831 int64_t external_clock_time;
834 double audio_diff_cum; /* used for AV difference average computation */
835 double audio_diff_avg_coef;
836 double audio_diff_threshold;
837 int audio_diff_avg_count;
840 int audio_hw_buf_size;
841 /* samples output by the codec. we reserve more space for avsync
843 uint8_t audio_buf[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2]
844 /* fixme, this is very gcc centric, what's aligned(x) in icc? */
845 __attribute__((aligned(16)));
846 unsigned int audio_buf_size; /* in bytes */
847 int audio_buf_index; /* in bytes */
849 uint8_t *audio_pkt_data;
852 int show_audio; /* if true, display audio samples */
853 int16_t sample_array[SAMPLE_ARRAY_SIZE];
854 int sample_array_index;
859 int subtitle_stream_changed;
860 AVStream *subtitle_st;
861 PacketQueue subtitleq;
862 SubPicture subpq[SUBPICTURE_QUEUE_SIZE];
863 int subpq_size, subpq_rindex, subpq_windex;
864 struct sxe_semaphore_s subpq_sem;
867 double frame_last_pts;
868 double frame_last_delay;
869 /* pts of last decoded frame / predicted pts of next decoded frame */
874 /* current displayed pts (different from video_clock
875 * if frame fifos are used */
876 double video_current_pts;
877 /* time (av_gettime) at which we updated video_current_pts - used
878 * to have running video pts */
879 int64_t video_current_pts_time;
880 VideoPicture pictq[VIDEO_PICTURE_QUEUE_SIZE];
881 int pictq_size, pictq_rindex, pictq_windex;
882 struct sxe_semaphore_s pictq_sem;
884 /* QETimer *video_timer; */
888 int width, height, xleft, ytop;
891 /* since we have only one decoding thread, we can use a global
892 variable instead of a thread local variable */
895 /* packet queue handling */
897 packet_queue_init(PacketQueue *q)
899 memset(q, 0, sizeof(PacketQueue));
900 SXE_SEMAPH_INIT(&q->sem);
904 packet_queue_flush(PacketQueue *q)
906 AVPacketList *pkt, *pkt1;
908 SXE_SEMAPH_LOCK(&q->sem);
909 for (pkt = q->first_pkt; pkt != NULL; pkt = pkt1) {
911 av_free_packet(&pkt->pkt);
918 SXE_SEMAPH_UNLOCK(&q->sem);
922 packet_queue_end(PacketQueue *q)
924 packet_queue_flush(q);
925 SXE_SEMAPH_FINI(&q->sem);
929 packet_queue_put(PacketQueue *q, AVPacket *pkt)
933 /* duplicate the packet */
934 if (pkt!=&flush_pkt && av_dup_packet(pkt) < 0)
937 pkt1 = av_malloc(sizeof(AVPacketList));
944 SXE_SEMAPH_LOCK(&q->sem);
950 q->last_pkt->next = pkt1;
953 q->size += pkt1->pkt.size;
954 /* XXX: should duplicate packet data in DV case */
955 SXE_SEMAPH_SIGNAL(&q->sem);
956 SXE_SEMAPH_UNLOCK(&q->sem);
961 packet_queue_abort(PacketQueue *q)
963 SXE_SEMAPH_LOCK(&q->sem);
965 q->abort_request = 1;
967 SXE_SEMAPH_SIGNAL(&q->sem);
968 SXE_SEMAPH_UNLOCK(&q->sem);
971 /* return < 0 if aborted, 0 if no packet and > 0 if packet. */
973 packet_queue_get(PacketQueue *q, AVPacket *pkt, int block)
974 __attribute__((unused));
977 packet_queue_get(PacketQueue *q, AVPacket *pkt, int block)
982 SXE_SEMAPH_LOCK(&q->sem);
985 if (q->abort_request) {
992 q->first_pkt = pkt1->next;
996 q->size -= pkt1->pkt.size;
1001 } else if (!block) {
1005 SXE_SEMAPH_WAIT(&q->sem);
1008 SXE_SEMAPH_UNLOCK(&q->sem);
1012 static uint64_t global_video_pkt_pts = AV_NOPTS_VALUE;
1015 my_get_buffer(struct AVCodecContext *c, AVFrame *pic)
1017 int ret= avcodec_default_get_buffer(c, pic);
1018 uint64_t *pts= av_malloc(sizeof(uint64_t));
1019 *pts= global_video_pkt_pts;
1025 my_release_buffer(struct AVCodecContext *c, AVFrame *pic)
1027 if(pic) av_freep(&pic->opaque);
1028 avcodec_default_release_buffer(c, pic);
1033 stream_component_open(VideoState *is, int stream_index, Lisp_Media_Stream *ms)
1036 media_substream *mss = NULL;
1037 AVFormatContext *ic = is->ic;
1038 AVCodecContext *enc;
1041 if (stream_index < 0 || (size_t)stream_index >= ic->nb_streams) {
1044 enc = ic->streams[stream_index]->codec;
1046 /* prepare audio output */
1047 if (enc->codec_type == AVMEDIA_TYPE_AUDIO) {
1049 wanted_spec.freq = enc->sample_rate;
1050 wanted_spec.format = AUDIO_S16SYS;
1052 /* hack for AC3. XXX: suppress that */
1053 if (enc->channels > 2)
1056 wanted_spec.channels = enc->channels;
1057 wanted_spec.silence = 0;
1058 wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;
1059 wanted_spec.callback = sdl_audio_callback;
1060 wanted_spec.userdata = is;
1062 is->audio_hw_buf_size = 0 /* spec.size */;
1065 codec = avcodec_find_decoder(enc->codec_id);
1066 enc->debug_mv = 0 /* debug_mv */;
1067 enc->debug = 0 /* debug */;
1068 enc->workaround_bugs = 0 /* workaround_bugs */;
1069 enc->lowres = 0 /* lowres */;
1071 enc->flags |= CODEC_FLAG_EMU_EDGE;
1072 enc->idct_algo = FF_IDCT_AUTO; /* idct; */
1074 enc->flags2 |= CODEC_FLAG2_FAST;
1075 enc->skip_frame = AVDISCARD_DEFAULT; /* skip_frame; */
1076 enc->skip_idct = AVDISCARD_DEFAULT; /* skip_idct; */
1077 enc->skip_loop_filter = AVDISCARD_DEFAULT; /* skip_loop_filter; */
1079 enc->error_resilience = FF_ER_CAREFUL; /* error_resilience; */
1081 enc->error_concealment = 3; /* error_concealment; */
1083 avcodec_open(enc, codec) < 0)
1085 if (1 /* thread_count */ > 1)
1086 avcodec_thread_init(enc, 1 /*thread_count*/);
1087 enc->thread_count= 1 /* thread_count */;
1089 /* create a substream */
1090 mss = make_media_substream_append(ms);
1092 switch ((unsigned int)enc->codec_type) {
1093 case AVMEDIA_TYPE_AUDIO:
1094 is->audio_stream = stream_index;
1095 is->audio_st = ic->streams[stream_index];
1096 is->audio_buf_size = 0;
1097 is->audio_buf_index = 0;
1099 /* init averaging filter */
1100 is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
1101 is->audio_diff_avg_count = 0;
1102 /* since we do not have a precise anough audio fifo fullness,
1103 we correct audio sync only if larger than this threshold */
1104 is->audio_diff_threshold =
1105 2.0 * SDL_AUDIO_BUFFER_SIZE / enc->sample_rate;
1107 memset(&is->audio_pkt, 0, sizeof(is->audio_pkt));
1108 packet_queue_init(&is->audioq);
1110 media_substream_type(mss) = MTYPE_AUDIO;
1111 media_ffmpeg_analyse_audio(mss, is->ic, stream_index);
1113 case AVMEDIA_TYPE_VIDEO:
1114 is->video_stream = stream_index;
1115 is->video_st = ic->streams[stream_index];
1117 is->frame_last_delay = 40e-3;
1119 int64_t tmp = av_gettime();
1120 is->frame_timer = (double)tmp / 1000000.0f;
1122 is->video_current_pts_time = av_gettime();
1124 packet_queue_init(&is->videoq);
1125 is->video_tid = 0 /* SDL_CreateThread(video_thread, is) */;
1127 enc-> get_buffer= my_get_buffer;
1128 enc->release_buffer= my_release_buffer;
1130 media_substream_type(mss) = MTYPE_VIDEO;
1131 media_ffmpeg_analyse_video(mss, is->ic, stream_index);
1133 case AVMEDIA_TYPE_SUBTITLE:
1134 is->subtitle_stream = stream_index;
1135 is->subtitle_st = ic->streams[stream_index];
1136 packet_queue_init(&is->subtitleq);
1138 is->subtitle_tid = 0 /*SDL_CreateThread(subtitle_thread, is)*/;
1147 stream_component_close(VideoState *is, int stream_index)
1149 AVFormatContext *ic = is->ic;
1150 AVCodecContext *enc;
1152 if (stream_index < 0 || (size_t)stream_index >= ic->nb_streams) {
1155 enc = ic->streams[stream_index]->codec;
1157 switch ((unsigned int)enc->codec_type) {
1158 case AVMEDIA_TYPE_AUDIO:
1159 packet_queue_abort(&is->audioq);
1163 packet_queue_end(&is->audioq);
1165 case AVMEDIA_TYPE_VIDEO:
1166 packet_queue_abort(&is->videoq);
1168 /* note: we also signal this mutex to make sure we deblock the
1169 video thread in all cases */
1170 SXE_SEMAPH_LOCK(&is->pictq_sem);
1171 SXE_SEMAPH_SIGNAL(&is->pictq_sem);
1172 SXE_SEMAPH_UNLOCK(&is->pictq_sem);
1174 SDL_WaitThread(is->video_tid, NULL);
1176 packet_queue_end(&is->videoq);
1178 case AVMEDIA_TYPE_SUBTITLE:
1179 packet_queue_abort(&is->subtitleq);
1181 /* note: we also signal this mutex to make sure we deblock the
1182 video thread in all cases */
1183 SXE_SEMAPH_LOCK(&is->subpq_sem);
1184 is->subtitle_stream_changed = 1;
1186 SXE_SEMAPH_SIGNAL(&is->subpq_sem);
1187 SXE_SEMAPH_UNLOCK(&is->subpq_sem);
1189 SDL_WaitThread(is->subtitle_tid, NULL);
1191 packet_queue_end(&is->subtitleq);
1198 switch ((unsigned int)enc->codec_type) {
1199 case AVMEDIA_TYPE_AUDIO:
1200 is->audio_st = NULL;
1201 is->audio_stream = -1;
1203 case AVMEDIA_TYPE_VIDEO:
1204 is->video_st = NULL;
1205 is->video_stream = -1;
1207 case AVMEDIA_TYPE_SUBTITLE:
1208 is->subtitle_st = NULL;
1209 is->subtitle_stream = -1;
1217 dump_stream_info(const AVFormatContext *s)
1219 static const char *keys[] = {
1220 "track", "title", "author", "copyright", "comment",
1221 "album", "date", "genre"
1223 static const size_t nkeys = sizeof(keys)/sizeof(keys[0]);
1225 AVDictionaryEntry *curr = NULL;
1226 if (! s->metadata) {
1227 fprintf(stderr, "No metadata\n");
1231 for (i = 0; i < nkeys; ++i ) {
1232 curr = av_dict_get(s->metadata,
1235 AV_DICT_IGNORE_SUFFIX);
1237 fprintf(stderr, "%s: %s\n", curr->key, curr->value);
1242 AV_SYNC_AUDIO_MASTER, /* default choice */
1243 AV_SYNC_VIDEO_MASTER,
1244 AV_SYNC_EXTERNAL_CLOCK, /* synchronize to an external clock */
1248 stream_open(char *filename, size_t filelen)
1250 VideoState *is = xnew(VideoState);
1251 AVFormatParameters params, *ap = ¶ms;
1254 is->filename = filename;
1255 is->filelen = filelen;
1256 is->iformat = av_find_input_format("fmt");
1260 /* initialise some semaphores */
1261 SXE_SEMAPH_INIT(&is->pictq_sem);
1262 SXE_SEMAPH_INIT(&is->subpq_sem);
1264 is->av_sync_type = AV_SYNC_AUDIO_MASTER;
1265 is->parse_tid = 0; /* SDL_CreateThread(decode_thread, is); */
1267 memset(ap, 0, sizeof(*ap));
1268 /* we force a pause when starting an RTSP stream */
1269 ap->initial_pause = 1;
1271 ap->width = 0; /* frame_width; */
1272 ap->height= 0; /* frame_height; */
1273 ap->time_base= (AVRational){1, 25};
1274 ap->pix_fmt = PIX_FMT_NONE; /* frame_pix_fmt; */
1276 err = avformat_open_input(&is->ic, is->filename, is->iformat, NULL /*ap*/);
1277 if (UNLIKELY(err < 0)) {
1278 FFMPEG_DEBUG_AVF("Could not open \"%s\" (errno %d)\n",
1290 /* main analysis function */
1291 static ms_driver_data_t
1292 new_media_ffmpeg_open(Lisp_Media_Stream *ms)
1294 /* the final result */
1295 VideoState *vs = NULL;
1296 int err = 0, use_play = 0;
1297 int wanted_audio_stream = 0;
1298 int wanted_video_stream = 0;
1299 int video_index = -1, audio_index = -1;
1300 mkind_file_properties *mkfp = NULL;
1307 if (media_stream_kind(ms) != MKIND_FILE) {
1312 mkfp = media_stream_kind_properties(ms).fprops;
1313 TO_EXTERNAL_FORMAT(LISP_STRING, mkfp->filename,
1314 MALLOC, (file, file_len), Qnil);
1315 if (UNLIKELY((vs = stream_open(file, file_len)) == NULL)) {
1316 media_stream_set_meths(ms, NULL);
1317 media_stream_driver(ms) = MDRIVER_UNKNOWN;
1321 #ifdef CONFIG_RTSP_DEMUXER
1322 use_play = (ic->iformat == &rtsp_demuxer);
1327 if (1 /* genpts */) {
1328 vs->ic->flags |= AVFMT_FLAG_GENPTS;
1332 err = avformat_find_stream_info(vs->ic, NULL);
1334 FFMPEG_DEBUG_AVF("\"%s\": "
1335 "could not find codec parameters\n",
1340 * ffplay maybe should not use url_feof() to test for the end */
1341 #if defined FFMPEG_URL_FOPEN_BIOCTX_STAR_STAR
1342 vs->ic->pb->eof_reached = 0;
1343 #elif defined FFMPEG_URL_FOPEN_BIOCTX_STAR
1344 vs->ic->pb.eof_reached = 0;
1348 /* now we can begin to play (RTSP stream only) */
1349 av_read_play(vs->ic);
1352 err = avformat_find_stream_info(vs->ic, NULL);
1354 FFMPEG_DEBUG_AVF("\"%s\": "
1355 "could not find codec parameters\n",
1361 for (size_t i = 0; i < vs->ic->nb_streams; i++) {
1362 AVCodecContext *enc = vs->ic->streams[i]->codec;
1363 switch ((unsigned int)enc->codec_type) {
1364 case AVMEDIA_TYPE_AUDIO:
1365 if ((audio_index < 0 || wanted_audio_stream-- > 0)) {
1369 case AVMEDIA_TYPE_VIDEO:
1370 if ((video_index < 0 || wanted_video_stream-- > 0)) {
1378 if (1 /* show_status */) {
1379 av_dump_format(vs->ic, 0, vs->filename, 0);
1380 dump_stream_info(vs->ic);
1383 /* open the streams */
1384 if (audio_index >= 0) {
1385 stream_component_open(vs, audio_index, ms);
1388 if (video_index >= 0) {
1389 stream_component_open(vs, video_index, ms);
1394 if (vs->video_stream < 0 && vs->audio_stream < 0) {
1395 FFMPEG_DEBUG_AVF("\"%s\": could not open codecs\n",
1400 /* keep the context */
1401 media_stream_data(ms) = vs;
1402 /* set me as driver indicator */
1403 media_stream_driver(ms) = MYSELF;
1413 new_media_ffmpeg_read(media_substream *mss, void *outbuf, size_t length)
1415 VideoState *is = media_stream_data(mss->up); /* was arg */
1417 AVPacket pkt1, *pkt = &pkt1;
1419 /* stuff normally set on the command line */
1420 int64_t start_time = AV_NOPTS_VALUE;
1422 av_init_packet(&flush_pkt);
1423 FFMPEG_CRITICAL("read\n");
1426 /* if seeking requested, we execute it */
1427 if (start_time != AV_NOPTS_VALUE) {
1430 timestamp = start_time;
1431 /* add the stream start time */
1432 if (ic->start_time != AV_NOPTS_VALUE)
1433 timestamp += ic->start_time;
1434 ret = av_seek_frame(ic, -1, timestamp, AVSEEK_FLAG_BACKWARD);
1436 fprintf(stderr, "%s: could not seek to position %0.3f\n",
1437 is->filename, (double)timestamp / AV_TIME_BASE);
1443 if (is->abort_request) {
1444 FFMPEG_DEBUG_AVF("\n");
1447 if (is->paused != is->last_paused) {
1448 is->last_paused = is->paused;
1450 av_read_pause(is->ic);
1452 av_read_play(is->ic);
1454 #ifdef CONFIG_RTSP_DEMUXER
1455 if (is->paused && is->ic->iformat == &rtsp_demuxer) {
1456 /* wait 10 ms to avoid trying to get another packet */
1463 int stream_index= -1;
1464 int64_t seek_target= is->seek_pos;
1466 if (is->video_stream >= 0)
1467 stream_index = is->video_stream;
1468 else if (is->audio_stream >= 0)
1469 stream_index = is->audio_stream;
1470 else if (is->subtitle_stream >= 0)
1471 stream_index = is->subtitle_stream;
1473 if (stream_index >= 0) {
1474 seek_target = av_rescale_q(
1475 seek_target, AV_TIME_BASE_Q,
1476 is->ic->streams[stream_index]->
1480 ret = av_seek_frame(is->ic, stream_index,
1481 seek_target, is->seek_flags);
1483 FFMPEG_DEBUG_AVS("\"%s: \""
1484 "error while seeking\n",
1487 if (is->audio_stream >= 0) {
1488 packet_queue_flush(&is->audioq);
1489 packet_queue_put(&is->audioq, &flush_pkt);
1491 if (is->subtitle_stream >= 0) {
1492 packet_queue_flush(&is->subtitleq);
1493 packet_queue_put(&is->subtitleq, &flush_pkt);
1495 if (is->video_stream >= 0) {
1496 packet_queue_flush(&is->videoq);
1497 packet_queue_put(&is->videoq, &flush_pkt);
1503 /* if the queue are full, no need to read more */
1504 if (is->audioq.size > MAX_AUDIOQ_SIZE ||
1505 is->videoq.size > MAX_VIDEOQ_SIZE ||
1506 is->subtitleq.size > MAX_SUBTITLEQ_SIZE ||
1507 #if defined FFMPEG_URL_FOPEN_BIOCTX_STAR_STAR
1508 url_feof(is->ic->pb)
1509 #elif defined FFMPEG_URL_FOPEN_BIOCTX_STAR
1510 url_feof(&is->ic->pb)
1517 ret = av_read_frame(is->ic, pkt);
1520 #if defined FFMPEG_URL_FOPEN_BIOCTX_STAR_STAR
1522 #elif defined FFMPEG_URL_FOPEN_BIOCTX_STAR
1526 usleep(100); /* wait for user event */
1531 if (pkt->stream_index == is->audio_stream) {
1532 packet_queue_put(&is->audioq, pkt);
1533 } else if (pkt->stream_index == is->video_stream) {
1534 packet_queue_put(&is->videoq, pkt);
1535 } else if (pkt->stream_index == is->subtitle_stream) {
1536 packet_queue_put(&is->subtitleq, pkt);
1538 av_free_packet(pkt);
1541 /* wait until the end */
1542 while (!is->abort_request) {
1548 /* close each stream */
1549 if (is->audio_stream >= 0)
1550 stream_component_close(is, is->audio_stream);
1551 if (is->video_stream >= 0)
1552 stream_component_close(is, is->video_stream);
1553 if (is->subtitle_stream >= 0)
1554 stream_component_close(is, is->subtitle_stream);
1556 avformat_close_input(&is->ic);
1557 is->ic = NULL; /* safety */
1559 url_set_interrupt_cb(NULL);
1565 event.type = FF_QUIT_EVENT;
1566 event.user.data1 = is;
1567 SDL_PushEvent(&event);
1574 new_media_ffmpeg_rewind(media_substream *mss)
1576 /* rewind the stream to the first frame */
1578 AVFormatContext *avfc;
1580 Lisp_Media_Stream *ms = mss->up;
1585 /* check the integrity of the media stream */
1586 if (media_stream_driver(ms) != MYSELF)
1589 FFMPEG_DEBUG_AVF("rewind substream 0x%lx\n",
1590 (long unsigned int)mss);
1592 /* fetch the format context */
1593 if (!(avfc = media_stream_data(ms)))
1596 si = (long int)mss->substream_data;
1597 avst = avfc->streams[si];
1598 if ((start_time = avst->start_time) < 0) {
1602 FFMPEG_DEBUG_AVF("rewind (idx:%ld) to %lld\n",
1603 si, (long long int)start_time);
1605 /* ... and reset the stream */
1606 res = av_seek_frame(avfc, -1, start_time, AVSEEK_FLAG_BACKWARD);
1609 FFMPEG_DEBUG_AVF("rewind succeeded\n");
1612 FFMPEG_DEBUG_AVF("rewind exitted with %d\n", res);
1619 media_ffmpeg_available_formats(void)
1621 Lisp_Object formats;
1622 AVInputFormat *avif;
1627 avif = first_iformat;
1631 const Lisp_Object fmtname =
1632 Fintern(build_string(avif->name), Qnil);
1633 formats = Fcons(fmtname, formats);