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;
132 AVDictionaryEntry *curr = NULL;
134 int chars_left = 4095;
136 avfc = media_stream_data(ms);
137 out = xmalloc_atomic(chars_left+1);
142 out[chars_left] = '\0';
144 /* cannot use ffmpeg on corrupt streams */
145 if (media_stream_driver(ms) != MYSELF || avfc == NULL)
148 if (! avfc->metadata)
152 static const char *keys[] = { "author", "title", "date" };
153 static const size_t nkeys = sizeof(keys)/sizeof(keys[0]);
156 for (i = 0; i < nkeys; ++i ) {
157 curr = av_dict_get(avfc->metadata,
160 AV_DICT_IGNORE_SUFFIX);
164 strncat(out, " :", chars_left);
169 strncat(out, curr->key, chars_left);
170 chars_left -= strlen(curr->key);
174 strncat(out, " \"", chars_left);
179 strncat(out, curr->value, chars_left);
180 chars_left -= strlen(curr->value);
184 strncat(out, "\"", chars_left);
195 media_ffmpeg_print(Lisp_Object ms, Lisp_Object pcfun, int ef)
200 static AVFormatContext*
201 media_ffmpeg_open_file(const char *file)
203 AVFormatContext *avfc = NULL;
206 if (avformat_open_input(&avfc, file, NULL, NULL) < 0) {
207 FFMPEG_DEBUG_AVF("opening file failed.\n");
211 /* Retrieve stream information */
212 if (avformat_find_stream_info(avfc, NULL) < 0) {
213 FFMPEG_DEBUG_AVS("opening stream inside file failed.\n");
214 avformat_close_input(&avfc);
223 media_ffmpeg_vio_read(void *h, unsigned char *buf, int size)
225 media_data *sd = (media_data*)h;
227 FFMPEG_DEBUG_AVS("reading %d bytes to 0x%x, respecting seek %ld\n",
228 size, (unsigned int)buf, sd->seek);
230 if ((long int)sd->length <= sd->seek) {
231 FFMPEG_DEBUG_AVS("eof\n");
235 memcpy(buf, sd->data+sd->seek, size);
242 media_ffmpeg_vio_seek(void *h, int64_t pos, int whence)
244 media_data *sd = (media_data*)h;
246 FFMPEG_DEBUG_AVS("seeking to %ld via %d\n", (long int)pos, whence);
253 sd->seek = sd->seek+pos;
256 sd->seek = sd->length+pos;
265 /** Size of probe buffer, for guessing file type from file contents. */
266 #define PROBE_BUF_MIN 2048
267 #define PROBE_BUF_MAX 131072
270 media_ffmpeg_open_data(char *data, size_t size)
272 AVFormatContext *avfc = NULL;
273 AVIOContext *avio = NULL;
274 media_data *sd = NULL;
275 unsigned char *buffer = NULL;
276 static const int bufsize = 65536;
278 /* initialise our media_data. Note that we need to use
279 * ffmpeg's malloc because it will free it on cleaning of the
280 * context and we don't want allocators corrupting each other.
282 sd = av_malloc(sizeof(media_data));
290 /* allocate the buffer */
291 buffer = av_malloc(bufsize);
295 /* create ffmpeg avio context. Note that at this point thea
296 * AVIOContext has lifetime control of the previously
297 * allocated sd and buffer.
299 avio = avio_alloc_context(buffer,
303 media_ffmpeg_vio_read,
305 media_ffmpeg_vio_seek);
307 /* create format context, and make it use the avio above.
308 Note that at this point avfc has lifetime control of avio,
309 through avformat_free_context */
310 avfc = avformat_alloc_context();
312 avfc->flags = AVFMT_FLAG_CUSTOM_IO;
315 if (avformat_open_input(&avfc, NULL, NULL, NULL) < 0) {
316 FFMPEG_DEBUG_AVF("opening file failed.\n");
317 /* Abundance of caution, as on failure open input
318 should clear the context, but when it does it also
319 sets avfc to NULL so this is safe. */
320 avformat_free_context(avfc);
324 /* Retrieve stream information */
325 if (avformat_find_stream_info(avfc,NULL) < 0) {
326 avformat_close_input(&avfc);
334 media_ffmpeg_close(ms_driver_data_t data)
336 AVFormatContext *avfc = (AVFormatContext*)data;
337 FFMPEG_DEBUG_AVF("closing AVFormatContext: 0x%lx\n",
338 (long unsigned int)avfc);
339 if (avfc && avfc->iformat)
340 avformat_close_input(&avfc);
344 media_ffmpeg_analyse_audio(media_substream *mss, AVFormatContext *avfc, int st)
346 mtype_audio_properties *mtap;
347 const char *name = NULL;
348 const char *codec_name = NULL;
349 /* libavformat cruft */
350 AVStream *avst = NULL;
351 AVCodecContext *avcc = NULL;
353 /* unpack the stream and codec context from the container, again */
355 avst = avfc->streams[st];
360 mtap = xnew_and_zero(mtype_audio_properties);
363 if (avfc && avfc->iformat)
364 name = avfc->iformat->name;
365 if (avcc && avcc->codec)
366 codec_name = avcc->codec->name;
369 mtap->codec_name = codec_name;
371 mtap->channels = avcc->channels;
372 mtap->samplerate = avcc->sample_rate;
373 mtap->bitrate = media_ffmpeg_bitrate(avcc);
375 /* samplewidth and framesize */
376 switch (avcc->sample_fmt) {
377 case AV_SAMPLE_FMT_U8:
378 mtap->samplewidth = 8;
379 mtap->framesize = mtap->channels * 1;
380 mtap->msf = sxe_msf_U8;
382 case AV_SAMPLE_FMT_S16:
383 mtap->samplewidth = 16;
384 mtap->framesize = mtap->channels * 2;
385 mtap->msf = sxe_msf_S16;
387 #if defined AV_SAMPLE_FMT_S24
388 case AV_SAMPLE_FMT_S24:
389 mtap->samplewidth = 32;
390 mtap->framesize = mtap->channels * 4;
391 mtap->msf = sxe_msf_S24;
393 #endif /* SAMPLE_FMT_S24 */
394 case AV_SAMPLE_FMT_S32:
395 mtap->samplewidth = 32;
396 mtap->framesize = mtap->channels * 4;
397 mtap->msf = sxe_msf_S32;
399 case AV_SAMPLE_FMT_FLT:
400 mtap->samplewidth = 8*sizeof(float);
401 mtap->framesize = mtap->channels * sizeof(float);
402 mtap->msf = sxe_msf_FLT;
404 case AV_SAMPLE_FMT_NONE:
406 mtap->samplewidth = 0;
410 mtap->endianness = 0;
413 media_substream_type_properties(mss).aprops = mtap;
414 media_substream_data(mss) = (void*)st;
418 media_ffmpeg_analyse_video(media_substream *mss, AVFormatContext *avfc, int st)
420 mtype_video_properties *mtvp;
421 const char *name = NULL;
422 const char *codec_name = NULL;
423 /* libavformat cruft */
424 AVStream *avst = NULL;
425 AVCodecContext *avcc = NULL;
427 /* unpack the stream and codec context from the container, again */
429 avst = avfc->streams[st];
434 mtvp = xnew_and_zero(mtype_video_properties);
437 if (avfc && avfc->iformat)
438 name = avfc->iformat->name;
439 if (avcc && avcc->codec)
440 codec_name = avcc->codec->name;
443 mtvp->codec_name = codec_name;
445 mtvp->bitrate = avcc->bit_rate;
446 mtvp->width = avcc->width;
447 mtvp->height = avcc->height;
448 mtvp->aspect_num = avcc->sample_aspect_ratio.num;
449 mtvp->aspect_den = avcc->sample_aspect_ratio.den;
452 mtvp->endianness = 0;
455 media_substream_type_properties(mss).vprops = mtvp;
456 media_substream_data(mss) = (void*)st;
459 /* main analysis function */
460 static ms_driver_data_t
461 media_ffmpeg_open(Lisp_Media_Stream *ms)
464 media_substream *mss;
465 /* libavformat stuff */
466 AVFormatContext *avfc = NULL;
467 AVStream *avst = NULL;
468 AVCodecContext *avcc = NULL;
474 switch (media_stream_kind(ms)) {
476 mkind_file_properties *mkfp = NULL;
481 mkfp = media_stream_kind_properties(ms).fprops;
482 TO_EXTERNAL_FORMAT(LISP_STRING, mkfp->filename,
483 ALLOCA, (file, file_len), Qnil);
484 SXE_SET_UNUSED(file_len);
486 avfc = media_ffmpeg_open_file(file);
488 media_stream_set_meths(ms, NULL);
489 media_stream_driver(ms) = MDRIVER_UNKNOWN;
493 /* store the filesize */
494 mkfp->filesize = avio_size(avfc->pb);
498 mkind_string_properties *mksp = NULL;
503 mksp = media_stream_kind_properties(ms).sprops;
504 data = mksp->stream_data;
506 avfc = media_ffmpeg_open_data(data, size);
509 media_stream_set_meths(ms, NULL);
510 media_stream_driver(ms) = MDRIVER_UNKNOWN;
518 case NUMBER_OF_MEDIA_KINDS:
524 /* check if there is at least one usable stream */
525 for (size_t st = 0; st < avfc->nb_streams; st++) {
526 avst = avfc->streams[st];
529 avcc->codec_id != CODEC_ID_NONE &&
530 avcc->codec_type != AVMEDIA_TYPE_DATA &&
531 (avc = avcodec_find_decoder(avcc->codec_id)) &&
532 (avc && (avcodec_open(avcc, avc) >= 0))) {
534 /* create a substream */
535 mss = make_media_substream_append(ms);
537 switch ((unsigned int)avcc->codec_type) {
538 case AVMEDIA_TYPE_VIDEO:
539 /* assign substream props */
540 media_substream_type(mss) = MTYPE_VIDEO;
541 media_ffmpeg_analyse_video(mss, avfc, st);
543 case AVMEDIA_TYPE_AUDIO:
544 /* assign substream props */
545 media_substream_type(mss) = MTYPE_AUDIO;
546 media_ffmpeg_analyse_audio(mss, avfc, st);
547 /* set some stream handlers */
548 media_stream_set_meths(ms, media_ffmpeg);
550 case AVMEDIA_TYPE_DATA:
551 media_substream_type(mss) = MTYPE_IMAGE;
554 media_substream_type(mss) = MTYPE_UNKNOWN;
560 /* keep the format context */
561 media_stream_data(ms) = avfc;
563 /* set me as driver indicator */
564 media_stream_driver(ms) = MYSELF;
571 handle_packet(AVFormatContext *avfc, AVPacket *pkt)
576 int ret, got_picture;
578 st = avfc->streams[pkt->stream_index];
580 /* XXX: allocate picture correctly */
581 avcodec_get_frame_defaults(&picture);
583 ret = avcodec_decode_video(
584 st->codec, &picture, &got_picture, pkt->data, pkt->size);
592 FFMPEG_DEBUG_AVF("got video frame\n");
602 media_ffmpeg_read(media_substream *mss, void *outbuf, size_t length)
604 /* read at most `length' frames into `outbuf' */
605 /* convert them to internal format */
607 Lisp_Media_Stream *ms = mss->up;
608 mtype_audio_properties *mtap;
609 media_sample_format_t *fmt;
611 AVFormatContext *avfc;
613 AVCodecContext *avcc;
617 /* the size we present here, is _not_ the size we want, however
618 * ffmpeg is quite pedantic about the buffer size,
619 * we just pass the least possible value here to please him */
620 int size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
623 long int bufseek = 0, si = -1;
624 int declen, dec, rf_status = 0;
626 /* check the integrity of the media stream */
627 if (media_stream_driver(ms) != MYSELF)
630 /* fetch the format context */
631 avfc = media_stream_data(ms);
636 si = (long int)mss->substream_data;
637 avst = avfc->streams[si];
641 /* unpack the substream */
642 if ((mtap = media_substream_type_properties(mss).aprops) == NULL) {
643 FFMPEG_DEBUG_AVS("stream information missing. Uh Oh.\n");
647 /* fetch audio info */
648 framesize = mtap->framesize;
651 /* initialise the packet */
652 pkt.pts = pkt.dts = pkt.size = 0;
653 FFMPEG_DEBUG_AVF("initialised packet: "
654 "pts:%lld dts:%lld psz:%d\n",
655 (long long int)pkt.pts,
656 (long long int)pkt.dts,
659 /* read a frame and decode it */
660 while ((size_t)bufseek <= length*framesize &&
661 (rf_status = av_read_frame(avfc, &pkt)) >= 0) {
662 if (pkt.stream_index != si) {
663 FFMPEG_DEBUG_AVF("SKIP reason: "
664 "sought after stream %ld, got %ld\n",
666 (long int)pkt.stream_index);
667 handle_packet(avfc, &pkt);
671 FFMPEG_DEBUG_AVF("read frame: "
672 "pts:%lld dts:%lld psz:%d\n",
673 (long long int)pkt.pts,
674 (long long int)pkt.dts,
678 /* decode the demuxed packet */
679 #ifdef HAVE_AVCODEC_DECODE_AUDIO2
680 /* prefer decode_audio2() if available */
681 size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
682 declen = avcodec_decode_audio2(
683 avcc, (void*)((char*)outbuf+bufseek),
684 &size, pkt.data, pkt.size);
685 #elif defined HAVE_AVCODEC_DECODE_AUDIO
686 declen = avcodec_decode_audio(
687 avcc, (void*)((char*)outbuf+bufseek),
688 &size, pkt.data, pkt.size);
693 if (dec > 0 && size > 0) {
694 FFMPEG_DEBUG_AVF("pts:%lld dts:%lld psz:%d s:%d d:%d\n",
695 (long long int)pkt.pts,
696 (long long int)pkt.dts,
697 pkt.size, size, declen);
699 /* memcpy(outbuf+bufseek, (char*)buffer, size); */
703 FFMPEG_DEBUG_AVF("packet state: "
704 "pts:%lld dts:%lld psz:%d\n",
705 (long long int)pkt.pts,
706 (long long int)pkt.dts,
708 av_free_packet(&pkt);
710 av_free_packet(&pkt);
712 FFMPEG_DEBUG_AVF("finished reading, bufseek=%ld, rf_status=%ld\n",
713 (long int)bufseek, (long int)rf_status);
715 /* convert the pig */
716 size = bufseek/framesize;
717 MEDIA_SAMPLE_FORMAT_UPSAMPLE(fmt)(outbuf, outbuf, size*mtap->channels);
724 media_ffmpeg_rewind(media_substream *mss)
726 /* rewind the stream to the first frame */
728 AVFormatContext *avfc;
730 Lisp_Media_Stream *ms = mss->up;
735 /* check the integrity of the media stream */
736 if (media_stream_driver(ms) != MYSELF)
739 FFMPEG_DEBUG_AVF("rewind substream 0x%lx\n",
740 (long unsigned int)mss);
742 /* fetch the format context */
743 if (!(avfc = media_stream_data(ms)))
746 si = (long int)mss->substream_data;
747 avst = avfc->streams[si];
748 if ((start_time = avst->start_time) < 0) {
752 FFMPEG_DEBUG_AVF("rewind (idx:%ld) to %lld\n",
753 si, (long long int)start_time);
755 /* ... and reset the stream */
756 res = av_seek_frame(avfc, si, AV_NOPTS_VALUE, AVSEEK_FLAG_BACKWARD);
759 FFMPEG_DEBUG_AVF("rewind succeeded\n");
762 FFMPEG_DEBUG_AVF("rewind exitted with %d\n", res);
769 * the size must be big enough to compensate the hardware audio buffersize size
771 #define SAMPLE_ARRAY_SIZE (2*65536)
772 #define VIDEO_PICTURE_QUEUE_SIZE 1
773 #define SUBPICTURE_QUEUE_SIZE 4
774 #define AUDIO_DIFF_AVG_NB 20
775 #define SDL_AUDIO_BUFFER_SIZE 1024
777 #define MAX_VIDEOQ_SIZE (5 * 256 * 1024)
778 #define MAX_AUDIOQ_SIZE (5 * 16 * 1024)
779 #define MAX_SUBTITLEQ_SIZE (5 * 16 * 1024)
781 #define FF_ALLOC_EVENT 0
782 #define FF_REFRESH_EVENT 1
783 #define FF_QUIT_EVENT 2
785 typedef struct PacketQueue {
786 AVPacketList *first_pkt, *last_pkt;
790 struct sxe_semaphore_s sem;
793 typedef struct VideoPicture {
794 /* presentation time stamp for this picture */
797 int width, height; /* source height & width */
801 typedef struct SubPicture {
802 double pts; /* presentation time stamp for this picture */
806 typedef struct VideoState {
809 AVInputFormat *iformat;
818 int dtg_active_format;
823 double external_clock; /* external clock base */
824 int64_t external_clock_time;
827 double audio_diff_cum; /* used for AV difference average computation */
828 double audio_diff_avg_coef;
829 double audio_diff_threshold;
830 int audio_diff_avg_count;
833 int audio_hw_buf_size;
834 /* samples output by the codec. we reserve more space for avsync
836 uint8_t audio_buf[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2]
837 /* fixme, this is very gcc centric, what's aligned(x) in icc? */
838 __attribute__((aligned(16)));
839 unsigned int audio_buf_size; /* in bytes */
840 int audio_buf_index; /* in bytes */
842 uint8_t *audio_pkt_data;
845 int show_audio; /* if true, display audio samples */
846 int16_t sample_array[SAMPLE_ARRAY_SIZE];
847 int sample_array_index;
852 int subtitle_stream_changed;
853 AVStream *subtitle_st;
854 PacketQueue subtitleq;
855 SubPicture subpq[SUBPICTURE_QUEUE_SIZE];
856 int subpq_size, subpq_rindex, subpq_windex;
857 struct sxe_semaphore_s subpq_sem;
860 double frame_last_pts;
861 double frame_last_delay;
862 /* pts of last decoded frame / predicted pts of next decoded frame */
867 /* current displayed pts (different from video_clock
868 * if frame fifos are used */
869 double video_current_pts;
870 /* time (av_gettime) at which we updated video_current_pts - used
871 * to have running video pts */
872 int64_t video_current_pts_time;
873 VideoPicture pictq[VIDEO_PICTURE_QUEUE_SIZE];
874 int pictq_size, pictq_rindex, pictq_windex;
875 struct sxe_semaphore_s pictq_sem;
877 /* QETimer *video_timer; */
881 int width, height, xleft, ytop;
884 /* since we have only one decoding thread, we can use a global
885 variable instead of a thread local variable */
888 /* packet queue handling */
890 packet_queue_init(PacketQueue *q)
892 memset(q, 0, sizeof(PacketQueue));
893 SXE_SEMAPH_INIT(&q->sem);
897 packet_queue_flush(PacketQueue *q)
899 AVPacketList *pkt, *pkt1;
901 SXE_SEMAPH_LOCK(&q->sem);
902 for (pkt = q->first_pkt; pkt != NULL; pkt = pkt1) {
904 av_free_packet(&pkt->pkt);
911 SXE_SEMAPH_UNLOCK(&q->sem);
915 packet_queue_end(PacketQueue *q)
917 packet_queue_flush(q);
918 SXE_SEMAPH_FINI(&q->sem);
922 packet_queue_put(PacketQueue *q, AVPacket *pkt)
926 /* duplicate the packet */
927 if (pkt!=&flush_pkt && av_dup_packet(pkt) < 0)
930 pkt1 = av_malloc(sizeof(AVPacketList));
937 SXE_SEMAPH_LOCK(&q->sem);
943 q->last_pkt->next = pkt1;
946 q->size += pkt1->pkt.size;
947 /* XXX: should duplicate packet data in DV case */
948 SXE_SEMAPH_SIGNAL(&q->sem);
949 SXE_SEMAPH_UNLOCK(&q->sem);
954 packet_queue_abort(PacketQueue *q)
956 SXE_SEMAPH_LOCK(&q->sem);
958 q->abort_request = 1;
960 SXE_SEMAPH_SIGNAL(&q->sem);
961 SXE_SEMAPH_UNLOCK(&q->sem);
964 /* return < 0 if aborted, 0 if no packet and > 0 if packet. */
966 packet_queue_get(PacketQueue *q, AVPacket *pkt, int block)
967 __attribute__((unused));
970 packet_queue_get(PacketQueue *q, AVPacket *pkt, int block)
975 SXE_SEMAPH_LOCK(&q->sem);
978 if (q->abort_request) {
985 q->first_pkt = pkt1->next;
989 q->size -= pkt1->pkt.size;
998 SXE_SEMAPH_WAIT(&q->sem);
1001 SXE_SEMAPH_UNLOCK(&q->sem);
1005 static uint64_t global_video_pkt_pts = AV_NOPTS_VALUE;
1008 my_get_buffer(struct AVCodecContext *c, AVFrame *pic)
1010 int ret= avcodec_default_get_buffer(c, pic);
1011 uint64_t *pts= av_malloc(sizeof(uint64_t));
1012 *pts= global_video_pkt_pts;
1018 my_release_buffer(struct AVCodecContext *c, AVFrame *pic)
1020 if(pic) av_freep(&pic->opaque);
1021 avcodec_default_release_buffer(c, pic);
1026 stream_component_open(VideoState *is, int stream_index, Lisp_Media_Stream *ms)
1029 media_substream *mss = NULL;
1030 AVFormatContext *ic = is->ic;
1031 AVCodecContext *enc;
1034 if (stream_index < 0 || (size_t)stream_index >= ic->nb_streams) {
1037 enc = ic->streams[stream_index]->codec;
1039 /* prepare audio output */
1040 if (enc->codec_type == AVMEDIA_TYPE_AUDIO) {
1042 wanted_spec.freq = enc->sample_rate;
1043 wanted_spec.format = AUDIO_S16SYS;
1045 /* hack for AC3. XXX: suppress that */
1046 if (enc->channels > 2)
1049 wanted_spec.channels = enc->channels;
1050 wanted_spec.silence = 0;
1051 wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;
1052 wanted_spec.callback = sdl_audio_callback;
1053 wanted_spec.userdata = is;
1055 is->audio_hw_buf_size = 0 /* spec.size */;
1058 codec = avcodec_find_decoder(enc->codec_id);
1059 enc->debug_mv = 0 /* debug_mv */;
1060 enc->debug = 0 /* debug */;
1061 enc->workaround_bugs = 0 /* workaround_bugs */;
1062 enc->lowres = 0 /* lowres */;
1064 enc->flags |= CODEC_FLAG_EMU_EDGE;
1065 enc->idct_algo = FF_IDCT_AUTO; /* idct; */
1067 enc->flags2 |= CODEC_FLAG2_FAST;
1068 enc->skip_frame = AVDISCARD_DEFAULT; /* skip_frame; */
1069 enc->skip_idct = AVDISCARD_DEFAULT; /* skip_idct; */
1070 enc->skip_loop_filter = AVDISCARD_DEFAULT; /* skip_loop_filter; */
1072 enc->error_resilience = FF_ER_CAREFUL; /* error_resilience; */
1074 enc->error_concealment = 3; /* error_concealment; */
1076 avcodec_open(enc, codec) < 0)
1078 if (1 /* thread_count */ > 1)
1079 avcodec_thread_init(enc, 1 /*thread_count*/);
1080 enc->thread_count= 1 /* thread_count */;
1082 /* create a substream */
1083 mss = make_media_substream_append(ms);
1085 switch ((unsigned int)enc->codec_type) {
1086 case AVMEDIA_TYPE_AUDIO:
1087 is->audio_stream = stream_index;
1088 is->audio_st = ic->streams[stream_index];
1089 is->audio_buf_size = 0;
1090 is->audio_buf_index = 0;
1092 /* init averaging filter */
1093 is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
1094 is->audio_diff_avg_count = 0;
1095 /* since we do not have a precise anough audio fifo fullness,
1096 we correct audio sync only if larger than this threshold */
1097 is->audio_diff_threshold =
1098 2.0 * SDL_AUDIO_BUFFER_SIZE / enc->sample_rate;
1100 memset(&is->audio_pkt, 0, sizeof(is->audio_pkt));
1101 packet_queue_init(&is->audioq);
1103 media_substream_type(mss) = MTYPE_AUDIO;
1104 media_ffmpeg_analyse_audio(mss, is->ic, stream_index);
1106 case AVMEDIA_TYPE_VIDEO:
1107 is->video_stream = stream_index;
1108 is->video_st = ic->streams[stream_index];
1110 is->frame_last_delay = 40e-3;
1112 int64_t tmp = av_gettime();
1113 is->frame_timer = (double)tmp / 1000000.0f;
1115 is->video_current_pts_time = av_gettime();
1117 packet_queue_init(&is->videoq);
1118 is->video_tid = 0 /* SDL_CreateThread(video_thread, is) */;
1120 enc-> get_buffer= my_get_buffer;
1121 enc->release_buffer= my_release_buffer;
1123 media_substream_type(mss) = MTYPE_VIDEO;
1124 media_ffmpeg_analyse_video(mss, is->ic, stream_index);
1126 case AVMEDIA_TYPE_SUBTITLE:
1127 is->subtitle_stream = stream_index;
1128 is->subtitle_st = ic->streams[stream_index];
1129 packet_queue_init(&is->subtitleq);
1131 is->subtitle_tid = 0 /*SDL_CreateThread(subtitle_thread, is)*/;
1140 stream_component_close(VideoState *is, int stream_index)
1142 AVFormatContext *ic = is->ic;
1143 AVCodecContext *enc;
1145 if (stream_index < 0 || (size_t)stream_index >= ic->nb_streams) {
1148 enc = ic->streams[stream_index]->codec;
1150 switch ((unsigned int)enc->codec_type) {
1151 case AVMEDIA_TYPE_AUDIO:
1152 packet_queue_abort(&is->audioq);
1156 packet_queue_end(&is->audioq);
1158 case AVMEDIA_TYPE_VIDEO:
1159 packet_queue_abort(&is->videoq);
1161 /* note: we also signal this mutex to make sure we deblock the
1162 video thread in all cases */
1163 SXE_SEMAPH_LOCK(&is->pictq_sem);
1164 SXE_SEMAPH_SIGNAL(&is->pictq_sem);
1165 SXE_SEMAPH_UNLOCK(&is->pictq_sem);
1167 SDL_WaitThread(is->video_tid, NULL);
1169 packet_queue_end(&is->videoq);
1171 case AVMEDIA_TYPE_SUBTITLE:
1172 packet_queue_abort(&is->subtitleq);
1174 /* note: we also signal this mutex to make sure we deblock the
1175 video thread in all cases */
1176 SXE_SEMAPH_LOCK(&is->subpq_sem);
1177 is->subtitle_stream_changed = 1;
1179 SXE_SEMAPH_SIGNAL(&is->subpq_sem);
1180 SXE_SEMAPH_UNLOCK(&is->subpq_sem);
1182 SDL_WaitThread(is->subtitle_tid, NULL);
1184 packet_queue_end(&is->subtitleq);
1191 switch ((unsigned int)enc->codec_type) {
1192 case AVMEDIA_TYPE_AUDIO:
1193 is->audio_st = NULL;
1194 is->audio_stream = -1;
1196 case AVMEDIA_TYPE_VIDEO:
1197 is->video_st = NULL;
1198 is->video_stream = -1;
1200 case AVMEDIA_TYPE_SUBTITLE:
1201 is->subtitle_st = NULL;
1202 is->subtitle_stream = -1;
1210 dump_stream_info(const AVFormatContext *s)
1212 static const char *keys[] = {
1213 "track", "title", "author", "copyright", "comment",
1214 "album", "date", "genre"
1216 static const size_t nkeys = sizeof(keys)/sizeof(keys[0]);
1218 AVDictionaryEntry *curr = NULL;
1219 if (! s->metadata) {
1220 fprintf(stderr, "No metadata\n");
1224 for (i = 0; i < nkeys; ++i ) {
1225 curr = av_dict_get(s->metadata,
1228 AV_DICT_IGNORE_SUFFIX);
1230 fprintf(stderr, "%s: %s\n", curr->key, curr->value);
1235 AV_SYNC_AUDIO_MASTER, /* default choice */
1236 AV_SYNC_VIDEO_MASTER,
1237 AV_SYNC_EXTERNAL_CLOCK, /* synchronize to an external clock */
1241 stream_open(char *filename, size_t filelen)
1243 VideoState *is = xnew(VideoState);
1244 AVFormatParameters params, *ap = ¶ms;
1247 is->filename = filename;
1248 is->filelen = filelen;
1249 is->iformat = av_find_input_format("fmt");
1253 /* initialise some semaphores */
1254 SXE_SEMAPH_INIT(&is->pictq_sem);
1255 SXE_SEMAPH_INIT(&is->subpq_sem);
1257 is->av_sync_type = AV_SYNC_AUDIO_MASTER;
1258 is->parse_tid = 0; /* SDL_CreateThread(decode_thread, is); */
1260 memset(ap, 0, sizeof(*ap));
1261 /* we force a pause when starting an RTSP stream */
1262 ap->initial_pause = 1;
1264 ap->width = 0; /* frame_width; */
1265 ap->height= 0; /* frame_height; */
1266 ap->time_base= (AVRational){1, 25};
1267 ap->pix_fmt = PIX_FMT_NONE; /* frame_pix_fmt; */
1269 err = avformat_open_input(&is->ic, is->filename, is->iformat, NULL /*ap*/);
1270 if (UNLIKELY(err < 0)) {
1271 FFMPEG_DEBUG_AVF("Could not open \"%s\" (errno %d)\n",
1283 /* main analysis function */
1284 static ms_driver_data_t
1285 new_media_ffmpeg_open(Lisp_Media_Stream *ms)
1287 /* the final result */
1288 VideoState *vs = NULL;
1289 int err = 0, use_play = 0;
1290 int wanted_audio_stream = 0;
1291 int wanted_video_stream = 0;
1292 int video_index = -1, audio_index = -1;
1293 mkind_file_properties *mkfp = NULL;
1300 if (media_stream_kind(ms) != MKIND_FILE) {
1305 mkfp = media_stream_kind_properties(ms).fprops;
1306 TO_EXTERNAL_FORMAT(LISP_STRING, mkfp->filename,
1307 MALLOC, (file, file_len), Qnil);
1308 if (UNLIKELY((vs = stream_open(file, file_len)) == NULL)) {
1309 media_stream_set_meths(ms, NULL);
1310 media_stream_driver(ms) = MDRIVER_UNKNOWN;
1314 #ifdef CONFIG_RTSP_DEMUXER
1315 use_play = (ic->iformat == &rtsp_demuxer);
1320 if (1 /* genpts */) {
1321 vs->ic->flags |= AVFMT_FLAG_GENPTS;
1325 err = avformat_find_stream_info(vs->ic, NULL);
1327 FFMPEG_DEBUG_AVF("\"%s\": "
1328 "could not find codec parameters\n",
1333 * ffplay maybe should not use url_feof() to test for the end */
1334 #if defined FFMPEG_URL_FOPEN_BIOCTX_STAR_STAR
1335 vs->ic->pb->eof_reached = 0;
1336 #elif defined FFMPEG_URL_FOPEN_BIOCTX_STAR
1337 vs->ic->pb.eof_reached = 0;
1341 /* now we can begin to play (RTSP stream only) */
1342 av_read_play(vs->ic);
1345 err = avformat_find_stream_info(vs->ic, NULL);
1347 FFMPEG_DEBUG_AVF("\"%s\": "
1348 "could not find codec parameters\n",
1354 for (size_t i = 0; i < vs->ic->nb_streams; i++) {
1355 AVCodecContext *enc = vs->ic->streams[i]->codec;
1356 switch ((unsigned int)enc->codec_type) {
1357 case AVMEDIA_TYPE_AUDIO:
1358 if ((audio_index < 0 || wanted_audio_stream-- > 0)) {
1362 case AVMEDIA_TYPE_VIDEO:
1363 if ((video_index < 0 || wanted_video_stream-- > 0)) {
1371 if (1 /* show_status */) {
1372 av_dump_format(vs->ic, 0, vs->filename, 0);
1373 dump_stream_info(vs->ic);
1376 /* open the streams */
1377 if (audio_index >= 0) {
1378 stream_component_open(vs, audio_index, ms);
1381 if (video_index >= 0) {
1382 stream_component_open(vs, video_index, ms);
1387 if (vs->video_stream < 0 && vs->audio_stream < 0) {
1388 FFMPEG_DEBUG_AVF("\"%s\": could not open codecs\n",
1393 /* keep the context */
1394 media_stream_data(ms) = vs;
1395 /* set me as driver indicator */
1396 media_stream_driver(ms) = MYSELF;
1406 new_media_ffmpeg_read(media_substream *mss, void *outbuf, size_t length)
1408 VideoState *is = media_stream_data(mss->up); /* was arg */
1410 AVPacket pkt1, *pkt = &pkt1;
1412 /* stuff normally set on the command line */
1413 int64_t start_time = AV_NOPTS_VALUE;
1415 av_init_packet(&flush_pkt);
1416 FFMPEG_CRITICAL("read\n");
1419 /* if seeking requested, we execute it */
1420 if (start_time != AV_NOPTS_VALUE) {
1423 timestamp = start_time;
1424 /* add the stream start time */
1425 if (ic->start_time != AV_NOPTS_VALUE)
1426 timestamp += ic->start_time;
1427 ret = av_seek_frame(ic, -1, timestamp, AVSEEK_FLAG_BACKWARD);
1429 fprintf(stderr, "%s: could not seek to position %0.3f\n",
1430 is->filename, (double)timestamp / AV_TIME_BASE);
1436 if (is->abort_request) {
1437 FFMPEG_DEBUG_AVF("\n");
1440 if (is->paused != is->last_paused) {
1441 is->last_paused = is->paused;
1443 av_read_pause(is->ic);
1445 av_read_play(is->ic);
1447 #ifdef CONFIG_RTSP_DEMUXER
1448 if (is->paused && is->ic->iformat == &rtsp_demuxer) {
1449 /* wait 10 ms to avoid trying to get another packet */
1456 int stream_index= -1;
1457 int64_t seek_target= is->seek_pos;
1459 if (is->video_stream >= 0)
1460 stream_index = is->video_stream;
1461 else if (is->audio_stream >= 0)
1462 stream_index = is->audio_stream;
1463 else if (is->subtitle_stream >= 0)
1464 stream_index = is->subtitle_stream;
1466 if (stream_index >= 0) {
1467 seek_target = av_rescale_q(
1468 seek_target, AV_TIME_BASE_Q,
1469 is->ic->streams[stream_index]->
1473 ret = av_seek_frame(is->ic, stream_index,
1474 seek_target, is->seek_flags);
1476 FFMPEG_DEBUG_AVS("\"%s: \""
1477 "error while seeking\n",
1480 if (is->audio_stream >= 0) {
1481 packet_queue_flush(&is->audioq);
1482 packet_queue_put(&is->audioq, &flush_pkt);
1484 if (is->subtitle_stream >= 0) {
1485 packet_queue_flush(&is->subtitleq);
1486 packet_queue_put(&is->subtitleq, &flush_pkt);
1488 if (is->video_stream >= 0) {
1489 packet_queue_flush(&is->videoq);
1490 packet_queue_put(&is->videoq, &flush_pkt);
1496 /* if the queue are full, no need to read more */
1497 if (is->audioq.size > MAX_AUDIOQ_SIZE ||
1498 is->videoq.size > MAX_VIDEOQ_SIZE ||
1499 is->subtitleq.size > MAX_SUBTITLEQ_SIZE ||
1500 #if defined FFMPEG_URL_FOPEN_BIOCTX_STAR_STAR
1501 url_feof(is->ic->pb)
1502 #elif defined FFMPEG_URL_FOPEN_BIOCTX_STAR
1503 url_feof(&is->ic->pb)
1510 ret = av_read_frame(is->ic, pkt);
1513 #if defined FFMPEG_URL_FOPEN_BIOCTX_STAR_STAR
1515 #elif defined FFMPEG_URL_FOPEN_BIOCTX_STAR
1519 usleep(100); /* wait for user event */
1524 if (pkt->stream_index == is->audio_stream) {
1525 packet_queue_put(&is->audioq, pkt);
1526 } else if (pkt->stream_index == is->video_stream) {
1527 packet_queue_put(&is->videoq, pkt);
1528 } else if (pkt->stream_index == is->subtitle_stream) {
1529 packet_queue_put(&is->subtitleq, pkt);
1531 av_free_packet(pkt);
1534 /* wait until the end */
1535 while (!is->abort_request) {
1541 /* close each stream */
1542 if (is->audio_stream >= 0)
1543 stream_component_close(is, is->audio_stream);
1544 if (is->video_stream >= 0)
1545 stream_component_close(is, is->video_stream);
1546 if (is->subtitle_stream >= 0)
1547 stream_component_close(is, is->subtitle_stream);
1549 avformat_close_input(&is->ic);
1550 is->ic = NULL; /* safety */
1552 url_set_interrupt_cb(NULL);
1558 event.type = FF_QUIT_EVENT;
1559 event.user.data1 = is;
1560 SDL_PushEvent(&event);
1567 new_media_ffmpeg_rewind(media_substream *mss)
1569 /* rewind the stream to the first frame */
1571 AVFormatContext *avfc;
1573 Lisp_Media_Stream *ms = mss->up;
1578 /* check the integrity of the media stream */
1579 if (media_stream_driver(ms) != MYSELF)
1582 FFMPEG_DEBUG_AVF("rewind substream 0x%lx\n",
1583 (long unsigned int)mss);
1585 /* fetch the format context */
1586 if (!(avfc = media_stream_data(ms)))
1589 si = (long int)mss->substream_data;
1590 avst = avfc->streams[si];
1591 if ((start_time = avst->start_time) < 0) {
1595 FFMPEG_DEBUG_AVF("rewind (idx:%ld) to %lld\n",
1596 si, (long long int)start_time);
1598 /* ... and reset the stream */
1599 res = av_seek_frame(avfc, -1, start_time, AVSEEK_FLAG_BACKWARD);
1602 FFMPEG_DEBUG_AVF("rewind succeeded\n");
1605 FFMPEG_DEBUG_AVF("rewind exitted with %d\n", res);
1612 media_ffmpeg_available_formats(void)
1614 Lisp_Object formats;
1615 AVInputFormat *avif;
1620 avif = first_iformat;
1624 const Lisp_Object fmtname =
1625 Fintern(build_string(avif->name), Qnil);
1626 formats = Fcons(fmtname, formats);