Statistics
| Branch: | Revision:

grapes / src / Chunkiser / output-stream-play.c @ 3a759615

History | View | Annotate | Download (22.3 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
  int64_t prev_pts, prev_dts;
48
  AVFormatContext *outctx;
49
  struct controls *c1;
50
  
51
  int playback_handleopened;
52
  snd_pcm_t *playback_handle;
53
  snd_pcm_hw_params_t *hw_params;
54
  int end;
55
  GdkPixmap *screen;
56
  pthread_mutex_t lockaudio;
57
  pthread_cond_t condaudio;
58
  pthread_mutex_t lockvideo;
59
  pthread_cond_t condvideo;
60
  struct PacketQueue videoq;
61
  struct PacketQueue audioq;
62
  pthread_t tid_video;
63
  pthread_t tid_audio;
64
  int64_t playout_delay;
65
  int64_t t0;
66
  int64_t pts0;
67
  ReSampleContext * rsc;
68
  int64_t last_video_pts;
69
  int cLimit;
70
  int consLate;
71
  int64_t ritardoMax;
72
};
73

    
74
struct controls {
75
  GtkWidget *d_area;
76
  GdkRectangle u_area;
77
  GdkGC *gc;
78
};
79

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

    
123
static snd_pcm_format_t sample_fmt_to_snd_pcm_format(enum AVSampleFormat  sample_fmt)
124
{
125
  switch((sample_fmt)){
126
    case AV_SAMPLE_FMT_U8  :return SND_PCM_FORMAT_U8;
127
    case AV_SAMPLE_FMT_S16 :return SND_PCM_FORMAT_S16;
128
    case AV_SAMPLE_FMT_S32 :return SND_PCM_FORMAT_S32;
129
    default           :return SND_PCM_FORMAT_UNKNOWN;
130
    //case AV_SAMPLE_FMT_FLT :return SND_PCM_FORMAT_FLOAT;
131
    //case AV_SAMPLE_FMT_DBL :
132
    //case AV_SAMPLE_FMT_NONE : return SND_PCM_FORMAT_UNKNOWN;break;
133
    //case AV_SAMPLE_FMT_NB :  
134
  }
135
}
136

    
137
static int enqueue(struct PacketQueue * q, AVPacket pkt)
138
{
139
  AVPacketList *pkt1;
140
  pkt1 = av_malloc(sizeof(AVPacketList));
141
  if (!pkt1)
142
    return -1;
143
  pkt1->pkt = pkt;
144
  pkt1->next = NULL;
145
  if (!q->last_pkt)
146
    q->first_pkt = pkt1;
147
  else
148
    q->last_pkt->next = pkt1;
149
  q->last_pkt = pkt1;
150
  q->length++;
151
  return 1;
152
}
153

    
154
static AVPacket dequeue(struct PacketQueue * q)
155
{
156
  AVPacketList *pkt1;
157
  AVPacket pkt;
158
  pkt1 = q->first_pkt;
159
    if (pkt1) {
160
      q->first_pkt = pkt1->next;
161
      if (!q->first_pkt)
162
        q->last_pkt = NULL;
163
      q->length--;
164
      pkt = pkt1->pkt;
165
      av_free(pkt1);
166
    }
167
  return pkt;
168

    
169
}
170

    
171
static 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)
172
{ /*http://www.equalarea.com/paul/alsa-audio.html*/
173

    
174
  int err;
175
    
176
  if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0) {
177
    fprintf (stderr, "cannot allocate hardware parameter structure (%s)\n",
178
      snd_strerror (err));
179
    exit (1);
180
  }
181
    
182
  if ((err = snd_pcm_hw_params_any (playback_handle, hw_params)) < 0) {
183
    fprintf (stderr, "cannot initialize hardware parameter structure (%s)\n",
184
      snd_strerror (err));
185
    exit (1);
186
  } 
187

    
188
  if ((err = snd_pcm_hw_params_set_access (playback_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
189
    fprintf (stderr, "cannot set access type (%s)\n",
190
      snd_strerror (err));
191
    exit (1);
192
  }
193

    
194
  if ((err = snd_pcm_hw_params_set_format (playback_handle, hw_params, format)) < 0) {
195
    fprintf (stderr, "cannot set sample format (%s)\n",
196
      snd_strerror (err));
197
    exit (1);
198
  } 
199

    
200
  if ((err = snd_pcm_hw_params_set_rate_near (playback_handle, hw_params,freq,0)) < 0) {    
201
    fprintf (stderr, "cannot set sample rate (%s)\n",
202
      snd_strerror (err));
203
    exit (1);
204
  }
205

    
206
  if ((err = snd_pcm_hw_params_set_channels (playback_handle, hw_params,channels)) < 0) {
207
    fprintf (stderr, "cannot set channel count (%s)\n",
208
      snd_strerror (err)); 
209
    exit (1);
210
  }
211

    
212
  
213
  if ((err = snd_pcm_hw_params (playback_handle, hw_params)) < 0) {
214
    fprintf (stderr, "cannot set parameters (%s)\n",
215
      snd_strerror (err));
216
    exit (1);
217
  }
218

    
219
  snd_pcm_hw_params_free (hw_params);
220

    
221
  if ((err = snd_pcm_prepare (playback_handle)) < 0) {
222
    fprintf (stderr, "cannot prepare audio interface for use (%s)\n",
223
      snd_strerror (err));
224
    exit (1);
225
  }
226

    
227
}
228

    
229
static int audio_write_packet(struct dechunkiser_ctx * o ,AVPacket * pkt)
230
{
231
  int res; 
232
  AVFormatContext * s1=o->outctx;
233
  snd_pcm_t * playback_handle=o->playback_handle;
234
  int size_out;
235
  int data_size=AVCODEC_MAX_AUDIO_FRAME_SIZE,len1;
236
  uint8_t *outbuf,*buffer_resample;
237

    
238
  if (pkt->size == 0)
239
    return 0;
240

    
241
  while (pkt->size > 0) { 
242
    outbuf = av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE*8);
243
    buffer_resample = av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE*8);
244
    data_size = AVCODEC_MAX_AUDIO_FRAME_SIZE*2;
245

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

    
248
    if (len1 < 0) {
249
      fprintf(stderr, "Error while decoding\n"); 
250
      return 0;
251
    }
252
    if(data_size > 0) {
253
      data_size/= s1->streams[pkt->stream_index]->codec->channels*pow(2,s1->streams[pkt->stream_index]->codec->sample_fmt);
254
      size_out=audio_resample(o->rsc,(short *)buffer_resample,(int16_t *)outbuf,data_size); 
255
      //size_out/= s1->streams[pkt->stream_index]->codec->channels*pow(2,s1->streams[pkt->stream_index]->codec->sample_fmt);
256
   
257
      if((res = snd_pcm_writei (playback_handle, buffer_resample,size_out)) <0) { 
258
        snd_pcm_recover(playback_handle,res,0);
259
      } else if(res==size_out){    
260
        pkt->size -= len1;  
261
        pkt->data += len1;
262
      }
263
    }
264
    av_free(outbuf);
265
    av_free(buffer_resample);
266
  }
267
  return 0;
268
}
269

    
270
static struct SwsContext *rescaler_context(AVCodecContext * c)
271
{
272
  int w, h;
273

    
274
  w = c->width;
275
  h = c->height;
276
  return sws_getContext(w, h, c->pix_fmt, w, h,PIX_FMT_RGB24,
277
                        SWS_BICUBIC, NULL, NULL, NULL);
278
}
279

    
280
/* FIXME: Return value??? What is it used for? */
281
static uint8_t *frame_display(struct dechunkiser_ctx *o, AVPacket pkt)
282
{ 
283
  GdkPixmap *screen=o->screen;
284
  AVFormatContext *ctx = o->outctx;
285
  int res = 1, decoded,height,width;
286
  static struct SwsContext *swsctx;
287
  AVFrame pic;
288
  int64_t now;
289
  int64_t difft;
290
  static AVFrame rgb;
291
  struct controls *c = o->c1;
292
  avcodec_get_frame_defaults(&pic);
293
  pic.pkt_pts=pkt.dts;
294
  res = avcodec_decode_video2(ctx->streams[pkt.stream_index]->codec,&pic, &decoded, &pkt);
295

    
296
  if (res < 0) {
297
    return NULL;
298
  }
299
  if (decoded) {
300
    now= av_gettime();
301
    if(AV_NOPTS_VALUE==pic.pkt_pts){
302
      pic.pkt_pts=av_rescale_q(pkt.dts,o->video_time_base,AV_TIME_BASE_Q);
303
    } else {
304
      pic.pkt_pts=av_rescale_q(pic.pkt_pts,o->video_time_base,AV_TIME_BASE_Q);
305
    }
306
    if(o->pts0==-1){
307
      o->pts0=pic.pkt_pts;
308
      o->last_video_pts=pic.pkt_pts;
309
    }
310

    
311
  difft=pic.pkt_pts-o->pts0+o->t0+o->playout_delay-now;
312
        if(difft<0){
313
                o->consLate++;
314
                if(difft<o->ritardoMax)
315
                        o->ritardoMax=difft;
316
        }        else        {
317
                o->consLate=0;
318
                o->ritardoMax=0;
319
        }
320
        if(o->consLate>=o->cLimit){
321
                o->playout_delay-=o->ritardoMax;
322
                o->consLate=0;
323
                o->ritardoMax=0;
324
        }
325
    if(difft>=0){
326
      usleep(difft);
327
    }else{
328
           return NULL;
329
    }
330
    
331
    if(o->last_video_pts<=pic.pkt_pts){
332
      o->last_video_pts=pic.pkt_pts;
333
      height=ctx->streams[pkt.stream_index]->codec->height;
334
      width=ctx->streams[pkt.stream_index]->codec->width;
335

    
336
      if (swsctx == NULL) { 
337
      swsctx = rescaler_context(ctx->streams[pkt.stream_index]->codec);
338
      avcodec_get_frame_defaults(&rgb);
339
      avpicture_alloc((AVPicture*)&rgb,PIX_FMT_RGB24,width,height);
340
      }
341
      if (swsctx) {
342
        sws_scale(swsctx,(const uint8_t* const*) pic.data, pic.linesize, 0,
343
                  height, rgb.data, rgb.linesize);
344
   
345
        gdk_draw_rgb_image(screen, c->gc, 0, 0, width, height,
346
                           GDK_RGB_DITHER_MAX, rgb.data[0], width*3 );
347
      
348
        gtk_widget_draw(GTK_WIDGET(c->d_area), &c->u_area);
349
        return rgb.data[0]; 
350
      }
351
    }
352
  }
353
  return NULL;
354
}
355

    
356
static void *videothread(void *p)
357
{ 
358
  AVPacket pkt;
359
  struct dechunkiser_ctx *o = p;
360

    
361
  if (gtk_events_pending()) {
362
    gtk_main_iteration_do(FALSE);
363
  }
364
  for(;!o->end;){
365
    pthread_mutex_lock(&o->lockvideo);
366
    while(o->videoq.length<1){
367
      pthread_cond_wait(&o->condvideo,&o->lockvideo);
368
    }
369
                if(!o->end){
370
            pkt=dequeue(&o->videoq);
371
            pthread_mutex_unlock(&o->lockvideo);
372
            frame_display(o,pkt);
373
            av_free_packet(&pkt);
374
          }else{
375
                        pthread_mutex_unlock(&o->lockvideo);}
376
                }
377
  pthread_exit(NULL);
378
}
379

    
380
static void *audiothread(void *p)
381
{
382
  AVPacket pkt;
383
  int64_t difft;
384
  int64_t now;
385
  struct dechunkiser_ctx *o = p;
386

    
387
  for(;!o->end;){
388
    pthread_mutex_lock(&o->lockaudio);
389
    while(o->audioq.length<1){
390
      pthread_cond_wait(&o->condaudio,&o->lockaudio);
391
    }
392
                if(!o->end){
393
            pkt=dequeue(&o->audioq);
394
            pthread_mutex_unlock(&o->lockaudio);
395

    
396
            difft=0;
397
                   now = av_gettime();
398
            difft=pkt.pts-o->pts0+o->t0+o->playout_delay-now;
399

    
400
                        if(difft<0){
401
                                o->consLate++;
402
                                if(difft<o->ritardoMax)
403
                                        o->ritardoMax=difft;
404
                        }        else        {
405
                                o->consLate=0;
406
                                o->ritardoMax=0;
407
                        }
408
                        if(o->consLate>=o->cLimit){
409
                                o->playout_delay-=o->ritardoMax;
410
                                o->consLate=0;
411
                                o->ritardoMax=0;
412
                        }
413
            if(difft>=0){
414
              usleep(difft);
415
              audio_write_packet(o, &pkt);
416

    
417
            }
418
            av_free_packet(&pkt);
419
          }else{
420
                        pthread_mutex_unlock(&o->lockaudio);
421
                }
422
}
423

    
424
  pthread_exit(NULL);
425
}
426

    
427
static gint delete_event(GtkWidget * widget, GdkEvent * event, struct dechunkiser_ctx * data)
428
{
429
  data->end=1;
430

    
431
  return (TRUE);
432
}
433

    
434
static gboolean expose_event(GtkWidget * widget, GdkEventExpose * event, struct dechunkiser_ctx * data)
435
{
436
  if ((data->screen != NULL) && (!data->end)) {
437
    gdk_draw_pixmap(widget->window,
438
        widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
439
        data->screen, event->area.x, event->area.y,
440
        event->area.x, event->area.y, event->area.width,
441
        event->area.height);
442
  }
443

    
444
  return TRUE;
445
}
446

    
447
static gint configure_event(GtkWidget * widget, GdkEventConfigure * event,
448
    struct dechunkiser_ctx * data)
449
{
450
  if (!data->screen) {
451
    data->screen = gdk_pixmap_new(widget->window, widget->allocation.width,
452
                widget->allocation.height, -1);
453
    gdk_draw_rectangle(data->screen, widget->style->white_gc, TRUE, 0, 0,
454
           widget->allocation.width, widget->allocation.height);
455
  }
456
  
457
  return TRUE;
458
}
459

    
460
static void *window_prepare(struct dechunkiser_ctx *o)
461
{
462
  int w;
463
  int h;
464
  GtkWidget *vbox;
465
  GtkWidget *hbox;
466
  GtkWidget *window;
467
  GdkColor black;
468
  GdkColor white;
469
  struct controls *c;
470
  w=o->width;
471
  h=o->height;
472
  c = malloc(sizeof(struct controls));
473
  if (c == NULL) {
474
    return NULL;
475
  }
476

    
477
  gtk_widget_set_default_colormap(gdk_rgb_get_cmap());
478
  gtk_widget_set_default_visual(gdk_rgb_get_visual());
479

    
480
  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
481
  gtk_window_set_default_size(GTK_WINDOW(window), w, h );
482
  gtk_window_set_title(GTK_WINDOW(window),"Player" );
483
  vbox = gtk_vbox_new(FALSE, 0);
484
  hbox = gtk_hbox_new(FALSE, 0);
485
  gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(vbox));
486

    
487

    
488
 
489
  //drawing area
490
  c->d_area = gtk_drawing_area_new();
491
  gtk_drawing_area_size(GTK_DRAWING_AREA(c->d_area), w, h);
492
  gtk_signal_connect(GTK_OBJECT(c->d_area), "expose_event",
493
           GTK_SIGNAL_FUNC(expose_event),o );
494
  gtk_signal_connect(GTK_OBJECT(c->d_area), "configure_event",
495
         GTK_SIGNAL_FUNC(configure_event),o );
496
  gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(c->d_area), FALSE, FALSE, 5);
497
  gtk_widget_show(c->d_area);
498

    
499

    
500
  gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(hbox), FALSE, FALSE, 5);
501

    
502
  gtk_widget_show(hbox);
503
  gtk_widget_show(vbox);
504
  gtk_widget_show(window);
505
  gtk_signal_connect(GTK_OBJECT(window), "delete_event",
506
         GTK_SIGNAL_FUNC(delete_event),o);
507

    
508

    
509
  c->u_area.x = 0;
510
  c->u_area.y = 0;
511
  c->u_area.width = c->d_area->allocation.width;
512
  c->u_area.height = c->d_area->allocation.height;
513
  c->gc = gdk_gc_new(c->d_area->window);
514

    
515
  gdk_color_black(gdk_colormap_get_system(), &black);
516
  gdk_color_white(gdk_colormap_get_system(), &white);
517
  gdk_gc_set_foreground(c->gc, &black);
518
  gdk_gc_set_background(c->gc, &white);
519

    
520
  return c;
521
}
522

    
523
static AVFormatContext *format_init(struct dechunkiser_ctx * o)
524
{
525
  AVFormatContext *of;
526
  AVOutputFormat *outfmt;
527
  
528
  av_register_all();
529

    
530
  outfmt = av_guess_format("null", NULL, NULL);
531
  of = avformat_alloc_context();
532
  if (of == NULL) {
533
    return NULL;
534
  }
535
  of->oformat = outfmt;
536

    
537
  return of;
538
}
539

    
540
static AVFormatContext *format_gen(struct dechunkiser_ctx * o, const uint8_t * data)
541
{
542
  uint8_t codec;
543
  codec = data[0];
544
  if ((codec < 128) && ((o->streams & 0x01) == 0)) {
545
    int width, height, frame_rate_n, frame_rate_d;
546

    
547
    o->streams |= 0x01;
548
    o->video_codec_id = libav_codec_id(codec);
549
    video_payload_header_parse(data, &codec, &width, &height, &frame_rate_n, &frame_rate_d);
550
    o->width = width;
551
    o->height= height;
552
    o->video_time_base.den = frame_rate_n;
553
    o->video_time_base.num = frame_rate_d;
554

    
555
  } else if ((codec > 128) && ((o->streams & 0x02) == 0)) {
556
    uint8_t channels;
557
    int sample_rate, frame_size;
558

    
559
    audio_payload_header_parse(data, &codec, &channels, &sample_rate, &frame_size);
560
    o->streams |= 0x02;
561
    o->audio_codec_id = libav_codec_id(codec);
562
    o->sample_rate = sample_rate;
563
    o->channels = channels;
564
    o->frame_size = frame_size;
565
    o->audio_time_base.num = frame_size;
566
    o->audio_time_base.den =sample_rate;
567

    
568

    
569
  }
570
  if (o->streams == o->selected_streams) {
571
    AVCodecContext *c;
572
    o->outctx = format_init(o);
573
    if (o->streams & 0x01) {
574
      AVCodec *vCodec;  
575
      av_new_stream(o->outctx, 0);
576
      c = o->outctx->streams[o->outctx->nb_streams - 1]->codec;
577
      c->codec_id = o->video_codec_id;
578
      c->codec_type = CODEC_TYPE_VIDEO;
579
      c->width = o->width;
580
      c->height= o->height;
581
      c->time_base.den = o->video_time_base.den;
582
      c->time_base.num = o->video_time_base.num;
583
      o->outctx->streams[0]->avg_frame_rate.num = o->video_time_base.den;
584
      o->outctx->streams[0]->avg_frame_rate.den = o->video_time_base.num;
585

    
586

    
587
      c->pix_fmt = PIX_FMT_YUV420P;
588
      vCodec = avcodec_find_decoder(o->outctx->streams[o->outctx->nb_streams - 1]->codec->codec_id);
589
      if(!vCodec) {
590
       fprintf (stderr, "Video unsupported codec\n");
591
       return NULL;
592
      }
593
      if(avcodec_open(o->outctx->streams[o->outctx->nb_streams - 1]->codec, vCodec)<0){
594
       fprintf (stderr, "could not open video codec\n");
595
       return NULL; // Could not open codec
596
      }
597

    
598

    
599
     o->c1 = window_prepare(o);
600
    }
601
    if (o->streams & 0x02) {
602
      AVCodec  *aCodec;
603
      av_new_stream(o->outctx, 1);
604
      c = o->outctx->streams[o->outctx->nb_streams - 1]->codec;
605
      c->codec_id = o->audio_codec_id;
606
      c->codec_type = CODEC_TYPE_AUDIO;
607
      c->sample_rate = o->sample_rate;
608
      c->channels = o->channels;
609
      c->frame_size = o->frame_size;
610
      c->time_base.num = o->audio_time_base.num;
611
      c->time_base.den = o->audio_time_base.den;
612

    
613
      aCodec = avcodec_find_decoder( o->outctx->streams[o->outctx->nb_streams - 1]->codec->codec_id);
614
      if(!aCodec) {
615
       fprintf (stderr, "Audio unsupported codec\n");
616
       return NULL;
617
      }
618
      if(avcodec_open(o->outctx->streams[o->outctx->nb_streams - 1]->codec, aCodec)<0){
619
       fprintf (stderr, "could not open audio codec\n");
620
       return NULL; // Could not open codec
621
      }
622
    }
623

    
624

    
625

    
626
    o->prev_pts = 0;
627
    o->prev_dts = 0;
628

    
629
    return o->outctx;
630
  }
631
  return NULL;
632
}
633

    
634
static struct dechunkiser_ctx *play_init(const char * fname, const char * config)
635
{
636
  struct dechunkiser_ctx *out;
637
  struct tag *cfg_tags;
638
  pthread_attr_t * thAttr=NULL;
639
  int err;
640
  const char * device_name="hw:0";
641
  out = malloc(sizeof(struct dechunkiser_ctx));
642
  if (out == NULL) {
643
    return NULL;
644
  }
645

    
646
  memset(out, 0, sizeof(struct dechunkiser_ctx));
647
  out->selected_streams = 0x01;
648
  cfg_tags = config_parse(config);
649
  if (cfg_tags) {
650
    const char *format;
651

    
652
    format = config_value_str(cfg_tags, "media");
653
    if (format) {
654
      if (!strcmp(format, "video")) {
655
        out->selected_streams = 0x01;
656
      } else if (!strcmp(format, "audio")) {
657
        out->selected_streams = 0x02;
658
      } else if (!strcmp(format, "av")) {
659
        out->selected_streams = 0x03;
660
      }
661
    }
662
  }
663
  out->playback_handleopened=0;
664
  out->end=0;
665
  out->playout_delay=1000000;
666
  out->pts0=-1;
667
  out->t0=0;
668
  out->consLate=0;
669
  out->cLimit=30;
670
  out->ritardoMax=0;
671
  if ((err = snd_pcm_open (&out->playback_handle, device_name, SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
672
   fprintf (stderr, "cannot open audio device %s (%s)\n", 
673
      device_name,
674
      snd_strerror (err)); 
675
   exit (1);
676
  }
677

    
678

    
679
  free(cfg_tags); 
680

    
681
  gtk_init(NULL, NULL);
682
  //gdk_rgb_init();
683
  pthread_mutex_init(&out->lockvideo,NULL);
684
  pthread_cond_init(&out->condvideo,NULL);
685
  pthread_mutex_init(&out->lockaudio,NULL);
686
  pthread_cond_init(&out->condaudio,NULL);
687
  pthread_create(&out->tid_video, thAttr, videothread, out);
688
  pthread_create(&out->tid_audio, thAttr, audiothread, out);
689

    
690
  return out;
691
}
692

    
693
static void play_write(struct dechunkiser_ctx *o, int id, uint8_t *data, int size)
694
{
695
  int header_size;
696
  int frames, i, media_type;
697
  uint8_t *p;
698

    
699

    
700
  if (data[0] == 0) {
701
    fprintf(stderr, "Error! strange chunk: %x!!!\n", data[0]);
702
    return;
703
  } else if (data[0] < 127) {
704
    header_size = VIDEO_PAYLOAD_HEADER_SIZE;
705
    media_type = 1;
706
  } else {
707
    header_size = AUDIO_PAYLOAD_HEADER_SIZE;
708
    media_type = 2;
709
  }
710

    
711
  if (o->outctx == NULL) { 
712
    o->outctx = format_gen(o, data);
713
    if (o->outctx == NULL) {    
714
      fprintf(stderr, "Format init failed\n");
715
      return;
716
    }
717
    
718
    if(o->t0==0){
719
      o->t0 = av_gettime();
720
    }
721
    av_set_parameters(o->outctx, NULL);
722
    dump_format(o->outctx, 0, "", 1);
723
  }
724
  if ((o->streams & media_type) == 0) {
725
    return;    /* Received a chunk for a non-selected stream */
726
  }
727

    
728
  frames = data[header_size - 1];
729
  p = data + header_size + FRAME_HEADER_SIZE * frames;
730
  for (i = 0; i < frames; i++) { 
731
    AVPacket pkt;
732
    int64_t pts, dts;
733
    int frame_size;
734
    frame_header_parse(data + header_size + FRAME_HEADER_SIZE * i,
735
                       &frame_size, &pts, &dts);
736

    
737
    //dprintf("Frame %d PTS1: %d\n", i, pts);
738
    av_init_packet(&pkt);
739

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

    
742
    if (pts != -1) {
743
      pts += (pts < o->prev_pts - ((1LL << 31) - 1)) ? ((o->prev_pts >> 32) + 1) << 32 : (o->prev_pts >> 32) << 32;
744
      //dprintf(" PTS2: %d\n", pts);
745
      o->prev_pts = pts;
746
      //dprintf("Frame %d has size %d --- PTS: %lld DTS: %lld\n", i, frame_size,
747
      //                                       av_rescale_q(pts, outctx->streams[0]->codec->time_base, AV_TIME_BASE_Q),
748
      //                                       av_rescale_q(dts, outctx->streams[0]->codec->time_base, AV_TIME_BASE_Q));
749

    
750
      pkt.pts = pts;
751
    } else {
752
      pkt.pts = AV_NOPTS_VALUE;
753
    }
754
    dts += (dts < o->prev_dts - ((1LL << 31) - 1)) ? ((o->prev_dts >> 32) + 1) << 32 : (o->prev_dts >> 32) << 32;
755
    o->prev_dts = dts;
756
    pkt.dts = dts;
757
    // pkt.data = p;
758
    pkt.data = av_mallocz(frame_size+FF_INPUT_BUFFER_PADDING_SIZE);
759
    memcpy(pkt.data,p,frame_size);
760
    p += frame_size;
761
    pkt.size = frame_size;
762

    
763
                if(pkt.stream_index==0){
764

    
765
      pthread_mutex_lock(&o->lockvideo);
766
      enqueue(&o->videoq,pkt);
767
      pthread_cond_signal(&o->condvideo);
768
      pthread_mutex_unlock(&o->lockvideo);
769
    } else {
770

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

    
773
      pkt.pts=av_rescale_q(pkt.pts,o->audio_time_base,AV_TIME_BASE_Q);
774

    
775
      pthread_mutex_lock(&o->lockaudio);
776

    
777
      if (o->playback_handleopened==0){
778
        snd_pcm_format_t snd_pcm_fmt=sample_fmt_to_snd_pcm_format(o->outctx->streams[pkt.stream_index]->codec->sample_fmt);
779

    
780
        if (snd_pcm_fmt==SND_PCM_FORMAT_UNKNOWN){
781
                       fprintf (stderr, "sample format not supported\n");
782
                return;
783
        }
784
        prepare_audio(o->playback_handle,o->hw_params,snd_pcm_fmt,o->channels,&o->sample_rate);
785
        o->playback_handleopened=1;
786
        o->rsc=av_audio_resample_init(o->outctx->streams[pkt.stream_index]->codec->channels,
787
                                      o->outctx->streams[pkt.stream_index]->codec->channels,
788
                                      o->sample_rate,
789
                                      o->outctx->streams[pkt.stream_index]->codec->sample_rate,
790
                                      o->outctx->streams[pkt.stream_index]->codec->sample_fmt,
791
                                      o->outctx->streams[pkt.stream_index]->codec->sample_fmt,16,10,0,0.8);
792
      }
793

    
794
      enqueue(&o->audioq,pkt);
795
      pthread_cond_signal(&o->condaudio);
796
      pthread_mutex_unlock(&o->lockaudio);
797
    }
798
  }
799
}
800

    
801
static void play_close(struct dechunkiser_ctx *s)
802
{
803
  int i;
804

    
805
  s->end=1;
806
  pthread_cond_signal(&s->condaudio);
807
  pthread_cond_signal(&s->condvideo);
808
  snd_pcm_close (s->playback_handle);
809
  audio_resample_close(s->rsc);
810
  pthread_join(s->tid_video, NULL);
811
  pthread_join(s->tid_audio, NULL);
812
  pthread_cond_destroy(&s->condvideo);
813
  pthread_mutex_destroy(&s->lockvideo);
814
  pthread_cond_destroy(&s->condaudio);
815
  pthread_mutex_destroy(&s->lockaudio);
816
 
817
  for (i = 0; i < s->outctx->nb_streams; i++) {
818
    av_metadata_free(&s->outctx->streams[i]->metadata);
819
    av_free(s->outctx->streams[i]->codec);
820
    av_free(s->outctx->streams[i]->info);
821
    av_free(s->outctx->streams[i]);
822
  }
823
  av_metadata_free(&s->outctx->metadata);
824
  free(s->outctx);
825
  //tobefreed c1->d_area, c1->gc
826
  //gtk_widget_destroy(window);
827
  free(s->c1);
828
  free(s);
829
}
830

    
831
struct dechunkiser_iface out_play = {
832
  .open = play_init,
833
  .write = play_write,
834
  .close = play_close,
835
};