Statistics
| Branch: | Revision:

grapes / src / Chunkiser / output-stream-play.c @ 751e0162

History | View | Annotate | Download (23.6 KB)

1
/*
2
 *  Copyright (c) 2010 Luca Abeni
3
 *  Copyright (c) 2011 Daniele Frisanco
4
 *
5
 *  This is free software; see gpl-3.0.txt
6
 */
7
#include <libavcodec/avcodec.h>
8
#include <libavformat/avformat.h>
9
#include <libswscale/swscale.h>
10
#include <stdio.h>
11
#include <math.h>
12
#include <string.h>
13
#include <pthread.h>
14
#include <gtk/gtk.h>
15
#include <alsa/asoundlib.h>
16

    
17
#include "int_coding.h"
18
#include "payload.h"
19
#include "config.h"
20
#include "dechunkiser_iface.h"
21

    
22
#ifndef MAX_STREAMS
23
#define MAX_STREAMS 20
24
#endif
25
#ifndef CODEC_TYPE_VIDEO
26
#define CODEC_TYPE_VIDEO AVMEDIA_TYPE_VIDEO
27
#define CODEC_TYPE_AUDIO AVMEDIA_TYPE_AUDIO
28
#endif
29

    
30
struct PacketQueue {
31
  AVPacketList *first_pkt;
32
  AVPacketList *last_pkt;
33
  int length;
34
} ;
35

    
36
struct dechunkiser_ctx {
37
  enum CodecID video_codec_id;
38
  enum CodecID audio_codec_id;
39
  int streams;
40
  int selected_streams;
41
  int width, height;
42
  int channels;
43
  int sample_rate, frame_size;
44
  AVRational video_time_base;
45
  AVRational audio_time_base;
46

    
47
  char *output_format;
48
  char *output_file;
49
  int64_t prev_pts, prev_dts;
50
  AVFormatContext *outctx;
51
  struct controls *c1;
52
  
53
  int playback_handleopened;
54
  snd_pcm_t *playback_handle;
55
  snd_pcm_hw_params_t *hw_params;
56
  int end;
57
  GdkPixmap *screen;
58
  pthread_mutex_t lockaudio;
59
  pthread_cond_t condaudio;
60
  pthread_mutex_t lockvideo;
61
  pthread_cond_t condvideo;
62
  struct PacketQueue videoq;
63
  struct PacketQueue audioq;
64
  pthread_t tid_video;
65
  pthread_t tid_audio;
66
  int64_t playout_delay;
67
  int64_t t0;
68
  int64_t pts0;
69
  ReSampleContext * rsc;
70
  int64_t last_video_pts;
71
  int cLimit;
72
  int consLate;
73
  int64_t ritardoMax;
74
};
75

    
76
static enum CodecID libav_codec_id(uint8_t mytype)
77
{
78
  switch (mytype) {
79
    case 1:
80
      return CODEC_ID_MPEG2VIDEO;
81
    case 2:
82
      return CODEC_ID_H261;
83
    case 3:
84
      return CODEC_ID_H263P;
85
    case 4:
86
      return CODEC_ID_MJPEG;
87
    case 5:
88
      return CODEC_ID_MPEG4;
89
    case 6:
90
      return CODEC_ID_FLV1;
91
    case 7:
92
      return CODEC_ID_SVQ3;
93
    case 8:
94
      return CODEC_ID_DVVIDEO;
95
    case 9:
96
      return CODEC_ID_H264;
97
    case 10:
98
      return CODEC_ID_THEORA;
99
    case 11:
100
      return CODEC_ID_SNOW;
101
    case 12:
102
      return CODEC_ID_VP6;
103
    case 13:
104
      return CODEC_ID_DIRAC;
105
    case 129:
106
      return CODEC_ID_MP3;
107
    case 130:
108
      return CODEC_ID_AAC;
109
    case 131:
110
      return CODEC_ID_AC3;
111
    case 132:
112
      return CODEC_ID_VORBIS;
113
    default:
114
      fprintf(stderr, "Unknown codec %d\n", mytype);
115
      return 0;
116
  }
117
}
118

    
119

    
120
struct controls {
121
  GtkWidget *d_area;
122
  GdkRectangle u_area;
123
  GdkGC *gc;
124
};
125
  
126

    
127
void *window_prepare(struct dechunkiser_ctx * o);
128

    
129

    
130
snd_pcm_format_t sample_fmt_to_snd_pcm_format(enum AVSampleFormat  sample_fmt)
131
{
132
  switch((sample_fmt)){
133
    case AV_SAMPLE_FMT_U8  :return SND_PCM_FORMAT_U8;
134
    case AV_SAMPLE_FMT_S16 :return SND_PCM_FORMAT_S16;
135
    case AV_SAMPLE_FMT_S32 :return SND_PCM_FORMAT_S32;
136
    default           :return SND_PCM_FORMAT_UNKNOWN;
137
    //case AV_SAMPLE_FMT_FLT :return SND_PCM_FORMAT_FLOAT;
138
    //case AV_SAMPLE_FMT_DBL :
139
    //case AV_SAMPLE_FMT_NONE : return SND_PCM_FORMAT_UNKNOWN;break;
140
    //case AV_SAMPLE_FMT_NB :  
141
  }
142
}
143

    
144
int enqueue(struct PacketQueue * q, AVPacket pkt)
145
{
146
  AVPacketList *pkt1;
147
  pkt1 = av_malloc(sizeof(AVPacketList));
148
  if (!pkt1)
149
    return -1;
150
  pkt1->pkt = pkt;
151
  pkt1->next = NULL;
152
  if (!q->last_pkt)
153
    q->first_pkt = pkt1;
154
  else
155
    q->last_pkt->next = pkt1;
156
  q->last_pkt = pkt1;
157
  q->length++;
158
  return 1;
159
}
160
AVPacket dequeue(struct PacketQueue * q)
161
{
162
  AVPacketList *pkt1;
163
  AVPacket pkt;
164
  pkt1 = q->first_pkt;
165
    if (pkt1) {
166
      q->first_pkt = pkt1->next;
167
      if (!q->first_pkt)
168
        q->last_pkt = NULL;
169
      q->length--;
170
      pkt = pkt1->pkt;
171
      av_free(pkt1);
172
    }
173
  return pkt;
174

    
175
}
176

    
177

    
178

    
179

    
180
void  prepare_audio ( snd_pcm_t * playback_handle, snd_pcm_hw_params_t * hw_params, const snd_pcm_format_t format, int channels, int *freq)
181
{ /*http://www.equalarea.com/paul/alsa-audio.html*/
182

    
183
  int err;
184
    
185
  if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0) {
186
    fprintf (stderr, "cannot allocate hardware parameter structure (%s)\n",
187
      snd_strerror (err));
188
    exit (1);
189
  }
190
    
191
  if ((err = snd_pcm_hw_params_any (playback_handle, hw_params)) < 0) {
192
    fprintf (stderr, "cannot initialize hardware parameter structure (%s)\n",
193
      snd_strerror (err));
194
    exit (1);
195
  } 
196

    
197
  if ((err = snd_pcm_hw_params_set_access (playback_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
198
    fprintf (stderr, "cannot set access type (%s)\n",
199
      snd_strerror (err));
200
    exit (1);
201
  }
202

    
203
  if ((err = snd_pcm_hw_params_set_format (playback_handle, hw_params, format)) < 0) {
204
    fprintf (stderr, "cannot set sample format (%s)\n",
205
      snd_strerror (err));
206
    exit (1);
207
  } 
208

    
209
  if ((err = snd_pcm_hw_params_set_rate_near (playback_handle, hw_params,freq,0)) < 0) {    
210
    fprintf (stderr, "cannot set sample rate (%s)\n",
211
      snd_strerror (err));
212
    exit (1);
213
  }
214

    
215
  if ((err = snd_pcm_hw_params_set_channels (playback_handle, hw_params,channels)) < 0) {
216
    fprintf (stderr, "cannot set channel count (%s)\n",
217
      snd_strerror (err)); 
218
    exit (1);
219
  }
220

    
221
  
222
  if ((err = snd_pcm_hw_params (playback_handle, hw_params)) < 0) {
223
    fprintf (stderr, "cannot set parameters (%s)\n",
224
      snd_strerror (err));
225
    exit (1);
226
  }
227

    
228
  snd_pcm_hw_params_free (hw_params);
229

    
230
  if ((err = snd_pcm_prepare (playback_handle)) < 0) {
231
    fprintf (stderr, "cannot prepare audio interface for use (%s)\n",
232
      snd_strerror (err));
233
    exit (1);
234
  }
235

    
236
}
237

    
238

    
239

    
240
static int audio_write_packet(struct dechunkiser_ctx * o ,AVPacket * pkt)
241
{
242
  int res; 
243
  AVFormatContext * s1=o->outctx;
244
  snd_pcm_t * playback_handle=o->playback_handle;
245
  int size_out;
246
  int data_size=AVCODEC_MAX_AUDIO_FRAME_SIZE,len1;
247
  uint8_t *outbuf,*buffer_resample;
248

    
249
  if (pkt->size == 0)
250
    return 0;
251

    
252
  while (pkt->size > 0) { 
253
    outbuf = av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE*8);
254
    buffer_resample = av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE*8);
255
    data_size = AVCODEC_MAX_AUDIO_FRAME_SIZE*2;
256

    
257
    len1 = avcodec_decode_audio3(s1->streams[pkt->stream_index]->codec, (int16_t *)outbuf, & data_size, pkt);
258

    
259
    if (len1 < 0) {
260
      fprintf(stderr, "Error while decoding\n"); 
261
      return 0;
262
    }
263
    if(data_size > 0) {
264
      data_size/= s1->streams[pkt->stream_index]->codec->channels*pow(2,s1->streams[pkt->stream_index]->codec->sample_fmt);
265
      size_out=audio_resample(o->rsc,(short *)buffer_resample,(int16_t *)outbuf,data_size); 
266
      //size_out/= s1->streams[pkt->stream_index]->codec->channels*pow(2,s1->streams[pkt->stream_index]->codec->sample_fmt);
267
   
268
      if((res = snd_pcm_writei (playback_handle, buffer_resample,size_out)) <0) { 
269
        snd_pcm_recover(playback_handle,res,0);
270
      } else if(res==size_out){    
271
        pkt->size -= len1;  
272
        pkt->data += len1;
273
      }
274
    }
275
    av_free(outbuf);
276
    av_free(buffer_resample);
277
  }
278
  return 0;
279
}
280

    
281

    
282

    
283
static struct SwsContext *rescaler_context(AVCodecContext * c)
284
{
285
  int w, h;
286

    
287
  w = c->width;
288
  h = c->height;
289
  return sws_getContext(w, h, c->pix_fmt, w, h,PIX_FMT_RGB24,
290
                        SWS_BICUBIC, NULL, NULL, NULL);
291
}
292

    
293

    
294
int64_t getmicro(){
295
  struct timespec r;
296
  clock_gettime(CLOCK_REALTIME, &r);
297
  return r.tv_nsec/1000+r.tv_sec*1000000;
298
}
299

    
300
/* FIXME: Return value??? What is it used for? */
301
uint8_t *frame_display(struct dechunkiser_ctx *o, AVPacket pkt)
302
{ 
303
  GdkPixmap *screen=o->screen;
304
  AVFormatContext *ctx = o->outctx;
305
  int res = 1, decoded,height,width;
306
  static struct SwsContext *swsctx;
307
  AVFrame pic;
308
  int64_t now;
309
  int64_t difft;
310
  static AVFrame rgb;
311
  struct controls *c = o->c1;
312
  avcodec_get_frame_defaults(&pic);
313
  pic.pkt_pts=pkt.dts;
314
  res = avcodec_decode_video2(ctx->streams[pkt.stream_index]->codec,&pic, &decoded, &pkt);
315

    
316
  if (res < 0) {
317
    return NULL;
318
  }
319
  if (decoded) {
320
    now=getmicro();
321
    if(AV_NOPTS_VALUE==pic.pkt_pts){
322
      pic.pkt_pts=av_rescale_q(pkt.dts,o->video_time_base,AV_TIME_BASE_Q);
323
    } else {
324
      pic.pkt_pts=av_rescale_q(pic.pkt_pts,o->video_time_base,AV_TIME_BASE_Q);
325
    }
326
    if(o->pts0==-1){
327
      o->pts0=pic.pkt_pts;
328
      o->last_video_pts=pic.pkt_pts;
329
    }
330

    
331
  difft=pic.pkt_pts-o->pts0+o->t0+o->playout_delay-now;
332
        if(difft<0){
333
                o->consLate++;
334
                if(difft<o->ritardoMax)
335
                        o->ritardoMax=difft;
336
        }        else        {
337
                o->consLate=0;
338
                o->ritardoMax=0;
339
        }
340
        if(o->consLate>=o->cLimit){
341
                o->playout_delay-=o->ritardoMax;
342
                o->consLate=0;
343
                o->ritardoMax=0;
344
        }
345
    if(difft>=0){
346
      usleep(difft);
347
    }else{
348
           return NULL;
349
    }
350
    
351
    if(o->last_video_pts<=pic.pkt_pts){
352
      o->last_video_pts=pic.pkt_pts;
353
      height=ctx->streams[pkt.stream_index]->codec->height;
354
      width=ctx->streams[pkt.stream_index]->codec->width;
355

    
356
      if (swsctx == NULL) { 
357
      swsctx = rescaler_context(ctx->streams[pkt.stream_index]->codec);
358
      avcodec_get_frame_defaults(&rgb);
359
      avpicture_alloc((AVPicture*)&rgb,PIX_FMT_RGB24,width,height);
360
      }
361
      if (swsctx) {
362
        sws_scale(swsctx,(const uint8_t* const*) pic.data, pic.linesize, 0,
363
                  height, rgb.data, rgb.linesize);
364
   
365
        gdk_draw_rgb_image(screen, c->gc, 0, 0, width, height,
366
                           GDK_RGB_DITHER_MAX, rgb.data[0], width*3 );
367
      
368
        gtk_widget_draw(GTK_WIDGET(c->d_area), &c->u_area);
369
        return rgb.data[0]; 
370
      }
371
    }
372
  }
373
  return NULL;
374
}
375

    
376

    
377

    
378
void * videothread(struct dechunkiser_ctx * o)
379
{ 
380
  AVPacket pkt;
381
  if (gtk_events_pending()) {
382
    gtk_main_iteration_do(FALSE);
383
  }
384
  for(;!o->end;){
385
    pthread_mutex_lock(&o->lockvideo);
386
    while(o->videoq.length<1){
387
      pthread_cond_wait(&o->condvideo,&o->lockvideo);
388
    }
389
                if(!o->end){
390
            pkt=dequeue(&o->videoq);
391
            pthread_mutex_unlock(&o->lockvideo);
392
            frame_display(o,pkt);
393
            av_free_packet(&pkt);
394
          }else{
395
                        pthread_mutex_unlock(&o->lockvideo);}
396
                }
397
  pthread_exit(NULL);
398
}
399

    
400

    
401
void * audiothread(struct dechunkiser_ctx * o)
402
{
403
  AVPacket pkt;
404
  int64_t difft;
405
  int64_t now;
406
  for(;!o->end;){
407
    pthread_mutex_lock(&o->lockaudio);
408
    while(o->audioq.length<1){
409
      pthread_cond_wait(&o->condaudio,&o->lockaudio);
410
    }
411
                if(!o->end){
412
            pkt=dequeue(&o->audioq);
413
            pthread_mutex_unlock(&o->lockaudio);
414

    
415
            difft=0;
416
                   now=getmicro();
417
            difft=pkt.pts-o->pts0+o->t0+o->playout_delay-now;
418

    
419
                        if(difft<0){
420
                                o->consLate++;
421
                                if(difft<o->ritardoMax)
422
                                        o->ritardoMax=difft;
423
                        }        else        {
424
                                o->consLate=0;
425
                                o->ritardoMax=0;
426
                        }
427
                        if(o->consLate>=o->cLimit){
428
                                o->playout_delay-=o->ritardoMax;
429
                                o->consLate=0;
430
                                o->ritardoMax=0;
431
                        }
432
            if(difft>=0){
433
              usleep(difft);
434
              audio_write_packet(o, &pkt);
435

    
436
            }
437
            av_free_packet(&pkt);
438
          }else{
439
                        pthread_mutex_unlock(&o->lockaudio);
440
                }
441
}
442

    
443
  pthread_exit(NULL);
444
}
445

    
446

    
447

    
448

    
449

    
450

    
451
static gint delete_event(GtkWidget * widget, GdkEvent * event, struct dechunkiser_ctx * data)
452
{
453
  data->end=1;
454

    
455
  return (TRUE);
456
}
457

    
458
static gboolean expose_event(GtkWidget * widget, GdkEventExpose * event, struct dechunkiser_ctx * data)
459
{
460
  if ((data->screen != NULL) && (!data->end)) {
461
    gdk_draw_pixmap(widget->window,
462
        widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
463
        data->screen, event->area.x, event->area.y,
464
        event->area.x, event->area.y, event->area.width,
465
        event->area.height);
466
  }
467

    
468
  return TRUE;
469
}
470

    
471
static gint configure_event(GtkWidget * widget, GdkEventConfigure * event,
472
    struct dechunkiser_ctx * data)
473
{
474
  if (!data->screen) {
475
    data->screen = gdk_pixmap_new(widget->window, widget->allocation.width,
476
                widget->allocation.height, -1);
477
    gdk_draw_rectangle(data->screen, widget->style->white_gc, TRUE, 0, 0,
478
           widget->allocation.width, widget->allocation.height);
479
  }
480
  
481
  return TRUE;
482
}
483

    
484
void *window_prepare(struct dechunkiser_ctx *o)
485
{ int w;
486
  int h;
487
  GdkGC *gc1;
488
  GtkWidget *vbox;
489
  GtkWidget *hbox;
490
  GtkWidget *window;
491
  GdkColor black;
492
  GdkColor white;
493
  struct controls *c;
494
  w=o->width;
495
  h=o->height;
496
  c = malloc(sizeof(struct controls));
497
  if (c == NULL) {
498
    return NULL;
499
  }
500

    
501
  gtk_widget_set_default_colormap(gdk_rgb_get_cmap());
502
  gtk_widget_set_default_visual(gdk_rgb_get_visual());
503

    
504
  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
505
  gtk_window_set_default_size(GTK_WINDOW(window), w, h );
506
  gtk_window_set_title(GTK_WINDOW(window),"Player" );
507
  vbox = gtk_vbox_new(FALSE, 0);
508
  hbox = gtk_hbox_new(FALSE, 0);
509
  gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(vbox));
510

    
511

    
512
 
513
  //drawing area
514
  c->d_area = gtk_drawing_area_new();
515
  gtk_drawing_area_size(GTK_DRAWING_AREA(c->d_area), w, h);
516
  gtk_signal_connect(GTK_OBJECT(c->d_area), "expose_event",
517
           GTK_SIGNAL_FUNC(expose_event),o );
518
  gtk_signal_connect(GTK_OBJECT(c->d_area), "configure_event",
519
         GTK_SIGNAL_FUNC(configure_event),o );
520
  gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(c->d_area), FALSE, FALSE, 5);
521
  gtk_widget_show(c->d_area);
522

    
523

    
524
  gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(hbox), FALSE, FALSE, 5);
525

    
526
  gtk_widget_show(hbox);
527
  gtk_widget_show(vbox);
528
  gtk_widget_show(window);
529
  gtk_signal_connect(GTK_OBJECT(window), "delete_event",
530
         GTK_SIGNAL_FUNC(delete_event),o);
531

    
532

    
533
  c->u_area.x = 0;
534
  c->u_area.y = 0;
535
  c->u_area.width = c->d_area->allocation.width;
536
  c->u_area.height = c->d_area->allocation.height;
537
  c->gc = gdk_gc_new(c->d_area->window);
538
  gc1 = gdk_gc_new(c->d_area->window);
539

    
540
  gdk_color_black(gdk_colormap_get_system(), &black);
541
  gdk_color_white(gdk_colormap_get_system(), &white);
542
  gdk_gc_set_foreground(c->gc, &black);
543
  gdk_gc_set_background(c->gc, &white);
544
  gdk_gc_set_foreground(gc1, &white);
545
  gdk_gc_set_background(gc1, &black);
546

    
547
  return c;
548
}
549

    
550

    
551
static AVFormatContext *format_init(struct dechunkiser_ctx * o)
552
{
553
  AVFormatContext *of;
554
  AVOutputFormat *outfmt;
555
  
556
  av_register_all();
557

    
558
  outfmt = av_guess_format(o->output_format, o->output_file, NULL);
559
  of = avformat_alloc_context();
560
  if (of == NULL) {
561
    return NULL;
562
  }
563
  of->oformat = outfmt;
564

    
565
  return of;
566
}
567

    
568
static AVFormatContext *format_gen(struct dechunkiser_ctx * o, const uint8_t * data)
569
{
570
  uint8_t codec;
571
  codec = data[0];
572
  if ((codec < 128) && ((o->streams & 0x01) == 0)) {
573
    int width, height, frame_rate_n, frame_rate_d;
574

    
575
    o->streams |= 0x01;
576
    o->video_codec_id = libav_codec_id(codec);
577
    video_payload_header_parse(data, &codec, &width, &height, &frame_rate_n, &frame_rate_d);
578
    o->width = width;
579
    o->height= height;
580
    o->video_time_base.den = frame_rate_n;
581
    o->video_time_base.num = frame_rate_d;
582

    
583
  } else if ((codec > 128) && ((o->streams & 0x02) == 0)) {
584
    uint8_t channels;
585
    int sample_rate, frame_size;
586

    
587
    audio_payload_header_parse(data, &codec, &channels, &sample_rate, &frame_size);
588
    o->streams |= 0x02;
589
    o->audio_codec_id = libav_codec_id(codec);
590
    o->sample_rate = sample_rate;
591
    o->channels = channels;
592
    o->frame_size = frame_size;
593
    o->audio_time_base.num = frame_size;
594
    o->audio_time_base.den =sample_rate;
595

    
596

    
597
  }
598
  if (o->streams == o->selected_streams) {
599
    AVCodecContext *c;
600
    o->outctx = format_init(o);
601
    if (o->streams & 0x01) {
602
      AVCodec *vCodec;  
603
      av_new_stream(o->outctx, 0);
604
      c = o->outctx->streams[o->outctx->nb_streams - 1]->codec;
605
      c->codec_id = o->video_codec_id;
606
      c->codec_type = CODEC_TYPE_VIDEO;
607
      c->width = o->width;
608
      c->height= o->height;
609
      c->time_base.den = o->video_time_base.den;
610
      c->time_base.num = o->video_time_base.num;
611
      o->outctx->streams[0]->avg_frame_rate.num = o->video_time_base.den;
612
      o->outctx->streams[0]->avg_frame_rate.den = o->video_time_base.num;
613

    
614

    
615
      c->pix_fmt = PIX_FMT_YUV420P;
616
      vCodec = avcodec_find_decoder(o->outctx->streams[o->outctx->nb_streams - 1]->codec->codec_id);
617
      if(!vCodec) {
618
       fprintf (stderr, "Video unsupported codec\n");
619
       return NULL;
620
      }
621
      if(avcodec_open(o->outctx->streams[o->outctx->nb_streams - 1]->codec, vCodec)<0){
622
       fprintf (stderr, "could not open video codec\n");
623
       return NULL; // Could not open codec
624
      }
625

    
626

    
627
     o->c1 = window_prepare(o);
628
    }
629
    if (o->streams & 0x02) {
630
      AVCodec  *aCodec;
631
      av_new_stream(o->outctx, 1);
632
      c = o->outctx->streams[o->outctx->nb_streams - 1]->codec;
633
      c->codec_id = o->audio_codec_id;
634
      c->codec_type = CODEC_TYPE_AUDIO;
635
      c->sample_rate = o->sample_rate;
636
      c->channels = o->channels;
637
      c->frame_size = o->frame_size;
638
      c->time_base.num = o->audio_time_base.num;
639
      c->time_base.den = o->audio_time_base.den;
640

    
641
      aCodec = avcodec_find_decoder( o->outctx->streams[o->outctx->nb_streams - 1]->codec->codec_id);
642
      if(!aCodec) {
643
       fprintf (stderr, "Audio unsupported codec\n");
644
       return NULL;
645
      }
646
      if(avcodec_open(o->outctx->streams[o->outctx->nb_streams - 1]->codec, aCodec)<0){
647
       fprintf (stderr, "could not open audio codec\n");
648
       return NULL; // Could not open codec
649
      }
650
    }
651

    
652

    
653

    
654
    o->prev_pts = 0;
655
    o->prev_dts = 0;
656

    
657
    return o->outctx;
658
  }
659
  return NULL;
660
}
661

    
662
static struct dechunkiser_ctx *play_init(const char * fname, const char * config)
663
{
664
  struct dechunkiser_ctx *out;
665
  struct tag *cfg_tags;
666
  pthread_attr_t * thAttr=NULL;
667
  int err;
668
  const char * device_name="hw:0";
669
  out = malloc(sizeof(struct dechunkiser_ctx));
670
  if (out == NULL) {
671
    return NULL;
672
  }
673

    
674
  memset(out, 0, sizeof(struct dechunkiser_ctx));
675
  out->output_format = strdup("nut");
676
  out->selected_streams = 0x01;
677
  if (fname) {
678
    out->output_file = strdup(fname);
679
  } else {
680
    out->output_file = strdup("/dev/stdout");
681
  }
682
  cfg_tags = config_parse(config);
683
  if (cfg_tags) {
684
    const char *format;
685

    
686
    format = config_value_str(cfg_tags, "format");
687
    if (format) {
688
      out->output_format = strdup(format);
689
    }
690
    format = config_value_str(cfg_tags, "media");
691
    if (format) {
692
      if (!strcmp(format, "video")) {
693
        out->selected_streams = 0x01;
694
      } else if (!strcmp(format, "audio")) {
695
        out->selected_streams = 0x02;
696
      } else if (!strcmp(format, "av")) {
697
        out->selected_streams = 0x03;
698
      }
699
    }
700
  }
701
  out->playback_handleopened=0;
702
  out->end=0;
703
  out->playout_delay=1000000;
704
  out->pts0=-1;
705
  out->t0=0;
706
  out->consLate=0;
707
  out->cLimit=30;
708
  out->ritardoMax=0;
709
  if ((err = snd_pcm_open (&out->playback_handle, device_name, SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
710
   fprintf (stderr, "cannot open audio device %s (%s)\n", 
711
      device_name,
712
      snd_strerror (err)); 
713
   exit (1);
714
  }
715

    
716

    
717
  free(cfg_tags); 
718

    
719
  gtk_init(NULL, NULL);
720
  //gdk_rgb_init();
721
  pthread_mutex_init(&out->lockvideo,NULL);
722
  pthread_cond_init(&out->condvideo,NULL);
723
  pthread_mutex_init(&out->lockaudio,NULL);
724
  pthread_cond_init(&out->condaudio,NULL);
725
  pthread_create(&out->tid_video,thAttr,videothread,out);
726
  pthread_create(&out->tid_audio,thAttr,audiothread,out);
727

    
728
  return out;
729
}
730

    
731

    
732

    
733
static void play_write(struct dechunkiser_ctx *o, int id, uint8_t *data, int size)
734
{
735
  int header_size;
736
  int frames, i, media_type;
737
  uint8_t *p;
738

    
739

    
740
  if (data[0] == 0) {
741
    fprintf(stderr, "Error! strange chunk: %x!!!\n", data[0]);
742
    return;
743
  } else if (data[0] < 127) {
744
    header_size = VIDEO_PAYLOAD_HEADER_SIZE;
745
    media_type = 1;
746
  } else {
747
    header_size = AUDIO_PAYLOAD_HEADER_SIZE;
748
    media_type = 2;
749
  }
750

    
751
  if (o->outctx == NULL) { 
752
    o->outctx = format_gen(o, data);
753
    if (o->outctx == NULL) {    
754
      fprintf(stderr, "Format init failed\n");
755
      return;
756
    }
757
    
758
    if(o->t0==0){
759
      o->t0=getmicro();
760
    }
761
    av_set_parameters(o->outctx, NULL);
762
    snprintf(o->outctx->filename, sizeof(o->outctx->filename), "%s", o->output_file);
763
    dump_format(o->outctx, 0, o->output_file, 1);
764
    url_fopen(&o->outctx->pb, o->output_file, URL_WRONLY );
765
  
766
    if (o->outctx->pb == NULL) {
767
      fprintf(stderr, "Cannot open %s!\n", o->output_file);
768
    }
769

    
770
    av_write_header(o->outctx);
771
  }
772
  if ((o->streams & media_type) == 0) {
773
    return;    /* Received a chunk for a non-selected stream */
774
  }
775

    
776
  frames = data[header_size - 1];
777
  p = data + header_size + FRAME_HEADER_SIZE * frames;
778
  for (i = 0; i < frames; i++) { 
779
    AVPacket pkt;
780
    int64_t pts, dts;
781
    int frame_size;
782
    frame_header_parse(data + header_size + FRAME_HEADER_SIZE * i,
783
                       &frame_size, &pts, &dts);
784

    
785
    //dprintf("Frame %d PTS1: %d\n", i, pts);
786
    av_init_packet(&pkt);
787

    
788
    pkt.stream_index = (media_type == 2) && (((o->streams & 0x01) == 0x01));
789

    
790
    if (pts != -1) {
791
      pts += (pts < o->prev_pts - ((1LL << 31) - 1)) ? ((o->prev_pts >> 32) + 1) << 32 : (o->prev_pts >> 32) << 32;
792
      //dprintf(" PTS2: %d\n", pts);
793
      o->prev_pts = pts;
794
      //dprintf("Frame %d has size %d --- PTS: %lld DTS: %lld\n", i, frame_size,
795
      //                                       av_rescale_q(pts, outctx->streams[0]->codec->time_base, AV_TIME_BASE_Q),
796
      //                                       av_rescale_q(dts, outctx->streams[0]->codec->time_base, AV_TIME_BASE_Q));
797

    
798

    
799
      if (pkt.stream_index==0){
800
        pkt.pts = av_rescale_q(pts, o->video_time_base, o->outctx->streams[0]->time_base);
801
      } else {
802
        pkt.pts = av_rescale_q(pts, o->audio_time_base, o->outctx->streams[1]->time_base);
803
      }
804
    } else {
805
      pkt.pts = AV_NOPTS_VALUE;
806
    }
807
    dts += (dts < o->prev_dts - ((1LL << 31) - 1)) ? ((o->prev_dts >> 32) + 1) << 32 : (o->prev_dts >> 32) << 32;
808
    o->prev_dts = dts;
809
    if (pkt.stream_index==0){
810
      pkt.dts = av_rescale_q(dts, o->video_time_base, o->outctx->streams[0]->time_base);
811
    } else {
812
      pkt.dts = av_rescale_q(dts, o->audio_time_base, o->outctx->streams[1]->time_base);
813
    }
814
    // pkt.data = p;
815
    pkt.data = av_mallocz(frame_size+FF_INPUT_BUFFER_PADDING_SIZE);
816
    memcpy(pkt.data,p,frame_size);
817
    p += frame_size;
818
    pkt.size = frame_size;
819

    
820
                if(pkt.stream_index==0){
821

    
822
      pthread_mutex_lock(&o->lockvideo);
823
      enqueue(&o->videoq,pkt);
824
      pthread_cond_signal(&o->condvideo);
825
      pthread_mutex_unlock(&o->lockvideo);
826
    } else {
827

    
828
      if(o->pts0==-1) o->pts0=av_rescale_q(pkt.pts,o->audio_time_base,AV_TIME_BASE_Q);
829

    
830
      pkt.pts=av_rescale_q(pkt.pts,o->audio_time_base,AV_TIME_BASE_Q);
831

    
832
      pthread_mutex_lock(&o->lockaudio);
833

    
834
      if (o->playback_handleopened==0){
835
        snd_pcm_format_t snd_pcm_fmt=sample_fmt_to_snd_pcm_format(o->outctx->streams[pkt.stream_index]->codec->sample_fmt);
836

    
837
        if (snd_pcm_fmt==SND_PCM_FORMAT_UNKNOWN){
838
                       fprintf (stderr, "sample format not supported\n");
839
                return;
840
        }
841
        prepare_audio(o->playback_handle,o->hw_params,snd_pcm_fmt,o->channels,&o->sample_rate);
842
        o->playback_handleopened=1;
843
        o->rsc=av_audio_resample_init(o->outctx->streams[pkt.stream_index]->codec->channels,
844
                                      o->outctx->streams[pkt.stream_index]->codec->channels,
845
                                      o->sample_rate,
846
                                      o->outctx->streams[pkt.stream_index]->codec->sample_rate,
847
                                      o->outctx->streams[pkt.stream_index]->codec->sample_fmt,
848
                                      o->outctx->streams[pkt.stream_index]->codec->sample_fmt,16,10,0,0.8);
849
      }
850

    
851
      enqueue(&o->audioq,pkt);
852
      pthread_cond_signal(&o->condaudio);
853
      pthread_mutex_unlock(&o->lockaudio);
854
    }
855
  }
856
}
857

    
858
static void play_close(struct dechunkiser_ctx *s)
859
{
860
  int i;
861
  int64_t last;
862
  s->end=1;
863
        pthread_cond_signal(&s->condaudio);
864
        pthread_cond_signal(&s->condvideo);
865
  snd_pcm_close (s->playback_handle);
866
  av_write_trailer(s->outctx);
867
  url_fclose(s->outctx->pb);
868
  audio_resample_close(s->rsc);
869
  pthread_join(&s->tid_video,NULL);
870
  pthread_join(&s->tid_audio,NULL);
871
  pthread_cond_destroy(&s->condvideo);
872
  pthread_mutex_destroy(&s->lockvideo);
873
  pthread_cond_destroy(&s->condaudio);
874
  pthread_mutex_destroy(&s->lockaudio);
875
 
876
  for (i = 0; i < s->outctx->nb_streams; i++) {
877
    av_metadata_free(&s->outctx->streams[i]->metadata);
878
    av_free(s->outctx->streams[i]->codec);
879
    av_free(s->outctx->streams[i]->info);
880
    av_free(s->outctx->streams[i]);
881
  }
882
  av_metadata_free(&s->outctx->metadata);
883
  free(s->outctx);
884
  free(s->output_format);
885
  free(s->output_file);
886
  free(s);
887
}
888

    
889
struct dechunkiser_iface out_play = {
890
  .open = play_init,
891
  .write = play_write,
892
  .close = play_close,
893
};