Ginga  0.13.6
 All Classes Namespaces Functions Variables
SDL2ffmpeg.h
1 /******************************************************************************
2 Este arquivo eh parte da implementacao do ambiente declarativo do middleware
3 Ginga (Ginga-NCL).
4 
5 Direitos Autorais Reservados (c) 1989-2007 PUC-Rio/Laboratorio TeleMidia
6 
7 Este programa eh software livre; voce pode redistribui-lo e/ou modificah-lo sob
8 os termos da Licenca Publica Geral GNU versao 2 conforme publicada pela Free
9 Software Foundation.
10 
11 Este programa eh distribuido na expectativa de que seja util, porem, SEM
12 NENHUMA GARANTIA; nem mesmo a garantia implicita de COMERCIABILIDADE OU
13 ADEQUACAO A UMA FINALIDADE ESPECIFICA. Consulte a Licenca Publica Geral do
14 GNU versao 2 para mais detalhes.
15 
16 Voce deve ter recebido uma copia da Licenca Publica Geral do GNU versao 2 junto
17 com este programa; se nao, escreva para a Free Software Foundation, Inc., no
18 endereco 59 Temple Street, Suite 330, Boston, MA 02111-1307 USA.
19 
20 Para maiores informacoes:
21 ncl @ telemidia.puc-rio.br
22 http://www.ncl.org.br
23 http://www.ginga.org.br
24 http://www.telemidia.puc-rio.br
25 ******************************************************************************
26 This file is part of the declarative environment of middleware Ginga (Ginga-NCL)
27 
28 Copyright: 1989-2007 PUC-RIO/LABORATORIO TELEMIDIA, All Rights Reserved.
29 
30 This program is free software; you can redistribute it and/or modify it under
31 the terms of the GNU General Public License version 2 as published by
32 the Free Software Foundation.
33 
34 This program is distributed in the hope that it will be useful, but WITHOUT ANY
35 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
36 PARTICULAR PURPOSE. See the GNU General Public License version 2 for more
37 details.
38 
39 You should have received a copy of the GNU General Public License version 2
40 along with this program; if not, write to the Free Software
41 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
42 
43 For further information contact:
44 ncl @ telemidia.puc-rio.br
45 http://www.ncl.org.br
46 http://www.ginga.org.br
47 http://www.telemidia.puc-rio.br
48 *******************************************************************************
49 Part of this file is extracted from ffplay
50 ffplay is part of FFmpeg library.
51 FFmpeg is free software licensed under the LGPL or GPL
52 Many thanks to ffmpeg developers and to the community that support them!
53 *******************************************************************************/
54 
55 #ifndef SDL2FFMPEG_H
56 #define SDL2FFMPEG_H
57 
58 #include "system/compat/SystemCompat.h"
59 using namespace ::br::pucrio::telemidia::ginga::core::system::compat;
60 
61 #include "system/thread/Thread.h"
62 using namespace ::br::pucrio::telemidia::ginga::core::system::thread;
63 
64 #include "mb/interface/IContinuousMediaProvider.h"
65 #include "mb/interface/sdl/SDLDeviceScreen.h"
66 
67 /* SDL2ffmpeg cplusplus compat begin */
68 extern "C" {
69 
70 #include <pthread.h>
71 #include <stdio.h>
72 #include <stdint.h>
73 #include <stdlib.h>
74 #include <string.h>
75 
76 #include "libavutil/avstring.h"
77 #include "libavutil/time.h"
78 #include "libavformat/avformat.h"
79 #include "libavdevice/avdevice.h"
80 #include "libswscale/swscale.h"
81 #include "libavutil/opt.h"
82 #include "libavcodec/avfft.h"
83 #include "libswresample/swresample.h"
84 
85 // AVFILTER BEGIN
86 # include "libavfilter/avcodec.h"
87 # include "libavfilter/avfilter.h"
88 # include "libavfilter/buffersink.h"
89 # include "libavfilter/buffersrc.h"
90 // AVFILTER end
91 
92 #include <inttypes.h>
93 #include <limits.h>
94 #include <math.h>
95 #include <pthread.h>
96 }
97 
98 #ifndef INT64_MIN
99 #define INT64_MIN (-__INT64_C(9223372036854775807)-1)
100 #endif //INT64_MIN
101 
102 #ifndef INT64_MAX
103 #define INT64_MAX (__INT64_C(9223372036854775807))
104 #endif //INT64_MAX
105 
106 /* SDL2ffmpeg cplusplus compat end*/
107 
108 
109 #include <SDL.h>
110 #include <SDL_thread.h>
111 
112 #define SCALEBITS 10
113 #define ONE_HALF (1 << (SCALEBITS - 1))
114 #define FIX(x) ((int) ((x) * (1<<SCALEBITS) + 0.5))
115 
116 #define RGB_TO_Y_CCIR(r, g, b) \
117 ((FIX(0.29900*219.0/255.0) * (r) + FIX(0.58700*219.0/255.0) * (g) + \
118  FIX(0.11400*219.0/255.0) * (b) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS)
119 
120 #define RGB_TO_U_CCIR(r1, g1, b1, shift)\
121 (((- FIX(0.16874*224.0/255.0) * r1 - FIX(0.33126*224.0/255.0) * g1 + \
122  FIX(0.50000*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS \
123  + shift)) + 128)
124 
125 #define RGB_TO_V_CCIR(r1, g1, b1, shift)\
126 (((FIX(0.50000*224.0/255.0) * r1 - FIX(0.41869*224.0/255.0) * g1 - \
127  FIX(0.08131*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + \
128  shift)) + 128)
129 
130 #define MAX_QUEUE_SIZE (15 * 1024 * 1024)
131 #define MIN_FRAMES 5
132 
133 /* SDL audio buffer size, in samples. Should be small to have precise
134  A/V sync as SDL does not have hardware buffer fullness info. */
135 #define SDL_AUDIO_BUFFER_SIZE 1024
136 
137 /* no AV sync correction is done if below the minimum AV sync threshold */
138 #define AV_SYNC_THRESHOLD_MIN 0.01
139 /* AV sync correction is done if above the maximum AV sync threshold */
140 #define AV_SYNC_THRESHOLD_MAX 0.1
141 /* If a frame duration is longer than this, it will not be duplicated to compensate AV sync */
142 #define AV_SYNC_FRAMEDUP_THRESHOLD 0.1
143 /* no AV correction is done if too big error */
144 #define AV_NOSYNC_THRESHOLD 10.0
145 
146 /* maximum audio speed change to get correct sync */
147 #define SAMPLE_CORRECTION_PERCENT_MAX 10
148 
149 /* external clock speed adjustment constants for realtime sources based on buffer fullness */
150 #define EXTERNAL_CLOCK_SPEED_MIN 0.900
151 #define EXTERNAL_CLOCK_SPEED_MAX 1.010
152 #define EXTERNAL_CLOCK_SPEED_STEP 0.001
153 
154 /* we use about AUDIO_DIFF_AVG_NB A-V differences to make the average */
155 #define AUDIO_DIFF_AVG_NB 20
156 
157 /* polls for possible required screen refresh at least this often, should be less than 1/fps */
158 #define REFRESH_RATE 0.01
159 
160 /* NOTE: the size must be big enough to compensate the hardware audio buffersize size */
161 /* TODO: We assume that a decoded and resampled frame fits into this buffer */
162 #define SAMPLE_ARRAY_SIZE (8 * 65536)
163 
164 #define VIDEO_PICTURE_QUEUE_SIZE 3
165 
166 #define ALPHA_BLEND(a, oldp, newp, s)\
167  ((((oldp << s) * (255 - (a))) + (newp * (a))) / (255 << s))
168 
169 #define RGBA_IN(r, g, b, a, s) {\
170  unsigned int v = ((const uint32_t *)(s))[0];\
171  a = (v >> 24) & 0xff;\
172  r = (v >> 16) & 0xff;\
173  g = (v >> 8) & 0xff;\
174  b = v & 0xff;\
175 }
176 
177 #define YUVA_IN(y, u, v, a, s, pal) {\
178  unsigned int val = ((const uint32_t *)(pal))[*(const uint8_t*)(s)];\
179  a = (val >> 24) & 0xff;\
180  y = (val >> 16) & 0xff;\
181  u = (val >> 8) & 0xff;\
182  v = val & 0xff;\
183 }
184 
185 #define YUVA_OUT(d, y, u, v, a) {\
186  ((uint32_t *)(d))[0] = (a << 24) | (y << 16) | (u << 8) | v;\
187 }
188 
189 #define BPP 1
190 
191 #include <cmath>
192 #include <string>
193 #include <iostream>
194 #include <set>
195 using namespace std;
196 
197 namespace br {
198 namespace pucrio {
199 namespace telemidia {
200 namespace ginga {
201 namespace core {
202 namespace mb {
203  typedef struct MyAVPacketList {
204  AVPacket pkt;
205  struct MyAVPacketList *next;
206  int serial;
207  } MyAVPacketList;
208 
209  typedef struct PacketQueue {
210  MyAVPacketList *first_pkt, *last_pkt;
211  int nb_packets;
212  int size;
213  int abort_request;
214  int serial;
215  SDL_mutex *mutex;
216  SDL_cond *cond;
217  } PacketQueue;
218 
219  typedef struct VideoPicture {
220  double pts; //presentation timestamp for this picture
221  double duration; //estimated duration based on frame rate
222  int64_t pos; //byte position in file
223  SDL_Texture* tex;
224  int width, height; // source height & width
225  int allocated;
226  int reallocate;
227  int serial;
228 
229  AVRational sar;
230 
231  //tmcode
232  AVFrame* src_frame;
233  } VideoPicture;
234 
235  typedef struct AudioParams {
236  int freq;
237  int channels;
238  int64_t channel_layout;
239  enum AVSampleFormat fmt;
240  int frame_size;
241  int bytes_per_sec;
242  } AudioParams;
243 
244  typedef struct Clock {
245  double pts; /* clock base */
246  double pts_drift; /* clock base minus time at which we updated the clock */
247  double last_updated;
248  double speed;
249  int serial; /* clock is based on a packet with this serial */
250  int paused;
251  int *queue_serial; /* pointer to the current packet queue serial, used for obsolete clock detection */
252  } Clock;
253 
254  typedef struct VideoState {
255  SDL_Thread *read_tid;
256  SDL_Thread *video_tid;
257  AVInputFormat *iformat;
258  int no_background;
259  int abort_request;
260  int force_refresh;
261  int paused;
262  int last_paused;
263  int queue_attachments_req;
264  int seek_req;
265  int seek_flags;
266  int64_t seek_pos;
267  int64_t seek_rel;
268  int read_pause_return;
269  AVFormatContext *ic;
270  int realtime;
271  int audio_finished;
272  int video_finished;
273 
274  Clock audclk;
275  Clock vidclk;
276  Clock extclk;
277 
278  int audio_stream;
279 
280  int av_sync_type;
281 
282  double audio_clock;
283  int audio_clock_serial;
284  double audio_diff_cum; /* used for AV difference average computation */
285  double audio_diff_avg_coef;
286  double audio_diff_threshold;
287  int audio_diff_avg_count;
288  AVStream *audio_st;
289  PacketQueue audioq;
290  int audio_hw_buf_size;
291  uint8_t silence_buf[SDL_AUDIO_BUFFER_SIZE];
292  uint8_t *audio_buf;
293  uint8_t *audio_buf1;
294  unsigned int audio_buf_size; /* in bytes */
295  unsigned int audio_buf1_size;
296  int audio_buf_index; /* in bytes */
297  int audio_write_buf_size;
298  int audio_buf_frames_pending;
299  AVPacket audio_pkt_temp;
300  AVPacket audio_pkt;
301  int audio_pkt_temp_serial;
302  int audio_last_serial;
303  struct AudioParams audio_src;
304  struct AudioParams audio_filter_src; // AVFILTER
305  struct AudioParams audio_tgt;
306  struct SwrContext *swr_ctx;
307  int frame_drops_early;
308  int frame_drops_late;
309  AVFrame *frame;
310  int64_t audio_frame_next_pts;
311  int16_t sample_array[SAMPLE_ARRAY_SIZE];
312  int sample_array_index;
313  int last_i_start;
314  RDFTContext *rdft;
315  int rdft_bits;
316  FFTSample *rdft_data;
317  int xpos;
318  double last_vis_time;
319 
320  double frame_timer;
321  double frame_last_returned_time;
322  double frame_last_filter_delay;
323  int video_stream;
324  AVStream *video_st;
325  PacketQueue videoq;
326  int64_t video_current_pos; // current displayed file pos
327  double max_frame_duration; // maximum duration of a frame - above this, we consider the jump a timestamp discontinuity
328  VideoPicture pictq[VIDEO_PICTURE_QUEUE_SIZE];
329  int pictq_size, pictq_rindex, pictq_windex;
330  SDL_mutex *pictq_mutex;
331  SDL_cond *pictq_cond;
332  SDL_Rect last_display_rect;
333 
334  char filename[1024];
335  int step;
336 
337  // AVFILTER begin
338  AVFilterContext *in_video_filter; // the first filter in the video chain
339  AVFilterContext *out_video_filter; // the last filter in the video chain
340  AVFilterContext *in_audio_filter; // the first filter in the audio chain
341  AVFilterContext *out_audio_filter; // the last filter in the audio chain
342  AVFilterGraph *agraph; // audio filter graph
343  // AVFILTER end
344 
345  int last_video_stream, last_audio_stream;
346 
347  SDL_cond *continue_read_thread;
348  } VideoState;
349 
350  class SDL2ffmpeg {
351  public:
352  static const short AV_SYNC_AUDIO_MASTER = 0;
353  static const short AV_SYNC_VIDEO_MASTER = 1;
354  static const short AV_SYNC_EXTERNAL_CLOCK = 2;
355 
356  private:
357  //stream status
358  static const short ST_PLAYING = 0;
359  static const short ST_PAUSED = 1;
360  static const short ST_STOPPED = 2;
361 
362  //desired audio specification default values
363  static const int ASD_SAMPLES = 4096;
364  static const int ASD_FREQ = 44100;
365  static const int ASD_CHANNELS = 2;
366 
367 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
368  static const int ASD_FORMAT = AUDIO_S16LSB;
369 #else
370  static const int ASD_FORMAT = AUDIO_S16MSB;
371 #endif
372 
373  int wanted_stream[AVMEDIA_TYPE_NB];
374  int seek_by_bytes;
375  int av_sync_type;
376  int64_t start_time;
377  int64_t duration;
378  int workaround_ffmpeg_bugs;
379  int fast;
380  int genpts;
381  int lowres;
382  int error_concealment;
383  int decoder_reorder_pts;
384  int framedrop;
385  int infinite_buffer;
386  int rdftspeed;
387 
388  char* vfilters;
389  char* afilters;
390 
391  AVPacket flush_pkt;
392 
393  VideoState* vs;
394 
395  static bool init;
396  static short refCount;
397 
398  static pthread_mutex_t aiMutex;
399  static set<SDL2ffmpeg*> aInstances;
400 
401  AVFrame vFrame;
402  AVPacket vPkt;
403 
404  int audioFreq;
405  Uint8 audioChannels;
406 
407  short status;
408  SDL_AudioSpec wantedSpec;
409  static SDL_AudioSpec spec;
410  SDL_AudioCVT acvt;
411  float soundLevel;
412  SDL_Texture* texture;
413 
414  bool hasSDLAudio;
415  bool reof;
416  bool hasPic;
417 
418  bool abortRequest;
419 
420  int64_t mono_cb_time;
421  int monoStep;
422 
424 
425  public:
426  SDL2ffmpeg(IContinuousMediaProvider* cmp, const char *filename);
427  ~SDL2ffmpeg();
428 
429  private:
430  void release();
431  void close(bool quit);
432 
433  string ffmpegErr(int err);
434 
435  void openStreams();
436  bool prepare();
437 
438  public:
439  bool hasVideoStream();
440  void play();
441  void stop();
442  void pause();
443  void resume();
444 
445  void getOriginalResolution(int* width, int* height);
446 
447  double getDuration();
448  double getPosition();
449  void seek(int64_t pos);
450 
451  void setTexture(SDL_Texture* texture);
452  bool hasTexture();
453  SDL_Texture* getTexture();
454 
455  bool hasPicture();
456 
457  void setSoundLevel(float level);
458 
459  bool getAudioSpec(
460  SDL_AudioSpec* spec, int sample_rate, uint8_t channels);
461 
462  static char* interleave(uint8_t* src, int srcLen, double ratio);
463 
464  static char* createCVT(
465  uint8_t* src, int srcLen, double ratio, int sampleSize);
466 
467  static void clamp(short* buf, int len);
468 
469  private:
470  static int cmp_audio_fmts(
471  enum AVSampleFormat fmt1,
472  int64_t channel_count1,
473  enum AVSampleFormat fmt2,
474  int64_t channel_count2);
475 
476  static int64_t get_valid_channel_layout(
477  int64_t channel_layout, int channels);
478 
479  int nts_packet_queue_put(PacketQueue *q, AVPacket *pkt);
480  int packet_queue_put(PacketQueue *q, AVPacket *pkt);
481  int packet_queue_put_nullpacket(PacketQueue *q, int stream_index);
482  void packet_queue_init(PacketQueue *q);
483  void packet_queue_flush(PacketQueue *q);
484  void packet_queue_destroy(PacketQueue *q);
485  void packet_queue_abort(PacketQueue *q);
486  void packet_queue_start(PacketQueue *q);
487  int packet_queue_get(
488  PacketQueue *q, AVPacket *pkt, int block, int* serial);
489 
490  void render_vp(VideoPicture* vp);
491 
492  void stream_close();
493 
494  double get_clock(Clock* c);
495  void set_clock_at(Clock* c, double pts, int serial, double time);
496  void set_clock(Clock* c, double pts, int serial);
497  void set_clock_speed(Clock* c, double speed);
498  void init_clock(Clock* c, int* queue_serial);
499  void sync_clock_to_slave(Clock* c, Clock* slave);
500  int get_master_sync_type();
501 
502  public:
503  double get_master_clock();
504 
505  private:
506  void check_external_clock_speed();
507 
508  void stream_seek(int64_t pos, int64_t rel, int seek_by_bytes);
509  void stream_toggle_pause();
510  void toggle_pause();
511  void step_to_next_frame();
512  double compute_target_delay(double delay);
513  static double vp_duration(VideoState *vs, VideoPicture *vp, VideoPicture *nextvp);
514  void pictq_next_picture();
515  int pictq_prev_picture();
516  void update_video_pts(double pts, int64_t pos, int serial);
517 
518  public:
519  static void video_refresh(void* opaque, double* remaining_time);
520  void alloc_picture();
521 
522  private:
523  int queue_picture(
524  AVFrame *src_frame,
525  double pts,
526  double duration,
527  int64_t pos,
528  int serial);
529 
530  int get_video_frame(AVFrame *frame, AVPacket* pkt, int* serial);
531 
532  //AVFILTER begin
533  int configure_filtergraph(
534  AVFilterGraph* graph,
535  const char* filtergraph,
536  AVFilterContext* source_ctx,
537  AVFilterContext* sink_ctx);
538 
539  int configure_video_filters(
540  AVFilterGraph* graph,
541  const char* vfilters,
542  AVFrame* frame);
543 
544  int configure_audio_filters(
545  const char *afilters,
546  int force_output_format);
547  //AVFILTER end
548 
549  static int video_thread(void *arg);
550 
551  int synchronize_audio(int nb_samples);
552 
553  int audio_decode_frame();
554  static void sdl_audio_callback(void *opaque, Uint8 *stream, int len);
555 
556  int audio_open(
557  int64_t wanted_channel_layout,
558  int wanted_nb_channels,
559  int wanted_sample_rate,
560  struct AudioParams *audio_hw_params);
561 
562  int stream_component_open(int stream_index);
563  void stream_component_close(int stream_index);
564 
565  static int decode_interrupt_cb(void *ctx);
566  static int is_realtime(AVFormatContext *s);
567  int read_init();
568  static int read_thread(void *arg);
569 
570  void stream_cycle_channel(int codec_type);
571 
572  static int lockmgr(void **mtx, enum AVLockOp op);
573 
574  static AVDictionary* filter_codec_opts(
575  AVDictionary *opts,
576  enum AVCodecID codec_id,
577  AVFormatContext *s,
578  AVStream *st,
579  AVCodec *codec);
580  };
581 }
582 }
583 }
584 }
585 }
586 }
587 
588 #endif /* SDL2FFMPEG_H */
Definition: NetworkUtil.h:53