Statistics
| Branch: | Revision:

grapes / src / Chunkiser / output-stream-play.c @ 2cbd9c9c

History | View | Annotate | Download (23.1 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 "ffmpeg_compat.h"
21
#include "dechunkiser_iface.h"
22

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

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

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

    
48
  int64_t prev_pts, prev_dts;
49
  AVFormatContext *outctx;
50
  struct controls *c1;
51
  
52
  snd_pcm_t *playback_handle;
53
  const char *device_name;
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
  ReSampleContext * rsc;
65
  struct SwsContext *swsctx;
66

    
67
  int64_t last_video_pts;
68

    
69
  int64_t playout_delay;
70
  int64_t t0;
71
  int64_t pts0;
72
  int cLimit;
73
  int consLate;
74
  int64_t maxDelay;
75
};
76

    
77
struct controls {
78
  GtkWidget *d_area;
79
  GdkRectangle u_area;
80
  GdkGC *gc;
81
};
82

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

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

    
140
/* FIXME: Can we receive a pointer to AVPacket? */
141
static int enqueue(struct PacketQueue * q, AVPacket pkt)
142
{
143
  AVPacketList *pkt1;
144

    
145
  pkt1 = av_malloc(sizeof(AVPacketList));
146
  if (pkt1 == NULL) {
147
    return -1;
148
  }
149

    
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
  }
157
  q->last_pkt = pkt1;
158
  q->length++;
159

    
160
  return 1;
161
}
162

    
163
/* FIXME: This looks broken! can return uninitialised pkt??? */
164
static AVPacket dequeue(struct PacketQueue *q)
165
{
166
  AVPacketList *pkt1;
167
  AVPacket pkt;
168

    
169
  pkt1 = q->first_pkt;
170
  if (pkt1) {
171
    q->first_pkt = pkt1->next;
172
    if (q->first_pkt == NULL) {
173
        q->last_pkt = NULL;
174
    }
175
    q->length--;
176
    pkt = pkt1->pkt;
177
    av_free(pkt1);
178
  }
179

    
180
  return pkt;
181
}
182

    
183
/* http://www.equalarea.com/paul/alsa-audio.html */
184
static int prepare_audio(snd_pcm_t *playback_handle, const snd_pcm_format_t format, int channels, int *freq)
185
{
186
  int err;
187
  snd_pcm_hw_params_t *hw_params;
188
    
189
  err = snd_pcm_hw_params_malloc(&hw_params);
190
  if (err < 0) {
191
    fprintf (stderr, "cannot allocate hardware parameter structure (%s)\n", snd_strerror(err));
192

    
193
    return -1;
194
  }
195
    
196
  err = snd_pcm_hw_params_any(playback_handle, hw_params);
197
  if (err < 0) {
198
    fprintf (stderr, "cannot initialize hardware parameter structure (%s)\n", snd_strerror(err));
199
    snd_pcm_hw_params_free(hw_params);
200

    
201
    return -2;
202
  } 
203

    
204
  err = snd_pcm_hw_params_set_access(playback_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED);
205
  if (err < 0) {
206
    fprintf (stderr, "cannot set access type (%s)\n", snd_strerror(err));
207
    snd_pcm_hw_params_free(hw_params);
208

    
209
    return -3;
210
  }
211

    
212
  err = snd_pcm_hw_params_set_format(playback_handle, hw_params, format);
213
  if (err < 0) {
214
    fprintf (stderr, "cannot set sample format (%s)\n", snd_strerror(err));
215
    snd_pcm_hw_params_free(hw_params);
216

    
217
    return -4;
218
  } 
219

    
220
  err = snd_pcm_hw_params_set_rate_near(playback_handle, hw_params, freq, 0);
221
  if (err < 0) {    
222
    fprintf (stderr, "cannot set sample rate (%s)\n", snd_strerror(err));
223
    snd_pcm_hw_params_free(hw_params);
224

    
225
    return -5;
226
  }
227

    
228
  err = snd_pcm_hw_params_set_channels(playback_handle, hw_params, channels);
229
  if (err < 0) {
230
    fprintf (stderr, "cannot set channel count (%s)\n", snd_strerror(err)); 
231
    snd_pcm_hw_params_free(hw_params);
232

    
233
    return -6;
234
  }
235

    
236
  err = snd_pcm_hw_params(playback_handle, hw_params);
237
  if (err < 0) {
238
    fprintf (stderr, "cannot set parameters (%s)\n", snd_strerror(err));
239
    snd_pcm_hw_params_free(hw_params);
240

    
241
    return -7;
242
  }
243

    
244
  snd_pcm_hw_params_free(hw_params);
245

    
246
  err = snd_pcm_prepare(playback_handle);
247
  if (err < 0) {
248
    fprintf (stderr, "cannot prepare audio interface for use (%s)\n", snd_strerror (err));
249

    
250
    return -8;
251
  }
252

    
253
  return 1;
254
}
255

    
256
static int audio_write_packet(struct dechunkiser_ctx *o, AVPacket pkt)
257
{
258
  int res; 
259
  AVFormatContext * s1=o->outctx;
260
  int size_out;
261
  int data_size=AVCODEC_MAX_AUDIO_FRAME_SIZE,len1;
262
  void *outbuf, *buffer_resample;
263

    
264
  if (pkt.size == 0) {
265
    return 0;
266
  }
267

    
268
  if (o->playback_handle == NULL) {
269
    res = snd_pcm_open(&o->playback_handle, o->device_name, SND_PCM_STREAM_PLAYBACK, 0);
270
    if (res  < 0) {
271
      fprintf (stderr, "cannot open audio device %s (%s)\n", o->device_name, snd_strerror(res)); 
272

    
273
      return -1;
274
    }
275
  }
276

    
277
  if (o->rsc == NULL) {
278
    snd_pcm_format_t snd_pcm_fmt;
279

    
280
    snd_pcm_fmt = sample_fmt_to_snd_pcm_format(o->outctx->streams[pkt.stream_index]->codec->sample_fmt);
281
    if (snd_pcm_fmt==SND_PCM_FORMAT_UNKNOWN){
282
      fprintf (stderr, "sample format not supported\n");
283

    
284
      return -2;
285
    }
286
    
287
    if (prepare_audio(o->playback_handle, snd_pcm_fmt, o->channels, &o->sample_rate) >= 0) {
288
      o->rsc = av_audio_resample_init(o->outctx->streams[pkt.stream_index]->codec->channels,
289
                                      o->outctx->streams[pkt.stream_index]->codec->channels,
290
                                      o->sample_rate,
291
                                      o->outctx->streams[pkt.stream_index]->codec->sample_rate,
292
                                      o->outctx->streams[pkt.stream_index]->codec->sample_fmt,
293
                                      o->outctx->streams[pkt.stream_index]->codec->sample_fmt, 16, 10, 0, 0.8);
294
    } else {
295
      return -2;
296
    }
297
  }
298

    
299
  while (pkt.size > 0) { 
300
    outbuf = av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE * 8);        /* FIXME: Why "* 8"? */
301
    buffer_resample = av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE * 8);
302
    data_size = AVCODEC_MAX_AUDIO_FRAME_SIZE * 2;                /* FIXME: Shouldn't this be "* 8" too? */
303

    
304
    len1 = avcodec_decode_audio3(s1->streams[pkt.stream_index]->codec, (int16_t *)outbuf, &data_size, &pkt);
305
    if (len1 < 0) {
306
      fprintf(stderr, "Error while decoding\n"); 
307

    
308
      return 0;
309
    }
310

    
311
    if(data_size > 0) {
312
      data_size /= s1->streams[pkt.stream_index]->codec->channels * pow(2, s1->streams[pkt.stream_index]->codec->sample_fmt); // FIXME: Remove the "pow()"
313
      size_out = audio_resample(o->rsc, buffer_resample, outbuf, data_size); 
314
      //size_out/= s1->streams[pkt->stream_index]->codec->channels*pow(2,s1->streams[pkt->stream_index]->codec->sample_fmt);
315
   
316
      res = snd_pcm_writei(o->playback_handle, buffer_resample, size_out);
317
      if (res < 0) { 
318
        snd_pcm_recover(o->playback_handle, res, 0);
319
      } else if(res == size_out) {        // FIXME: WTF?
320
        pkt.size -= len1;
321
        pkt.data += len1;
322
      }
323
    }
324
    av_free(outbuf);
325
    av_free(buffer_resample);
326
  }
327

    
328
  return 0;                                // FIXME: Return size
329
}
330

    
331
static struct SwsContext *rescaler_context(AVCodecContext * c)
332
{
333
  int w, h;
334

    
335
  w = c->width;
336
  h = c->height;
337
  return sws_getContext(w, h, c->pix_fmt, w, h,PIX_FMT_RGB24,
338
                        SWS_BICUBIC, NULL, NULL, NULL);
339
}
340

    
341
/* FIXME: Return value??? What is it used for? */
342
static uint8_t *frame_display(struct dechunkiser_ctx *o, AVPacket pkt)
343
{ 
344
  GdkPixmap *screen = o->screen;
345
  AVFormatContext *ctx = o->outctx;
346
  int res = 1, decoded, height, width;
347
  AVFrame pic;
348
  int64_t now;
349
  int64_t difft;
350
  static AVFrame rgb;
351
  struct controls *c = o->c1;
352

    
353
  avcodec_get_frame_defaults(&pic);
354
  pic.pkt_pts = pkt.dts;
355
  res = avcodec_decode_video2(ctx->streams[pkt.stream_index]->codec, &pic, &decoded, &pkt);
356
  if (res < 0) {
357
    return NULL;
358
  }
359

    
360
  if (decoded) {
361
    if(AV_NOPTS_VALUE == pic.pkt_pts) {
362
      pic.pkt_pts = av_rescale_q(pkt.dts, o->video_time_base, AV_TIME_BASE_Q);
363
    } else {
364
      pic.pkt_pts = av_rescale_q(pic.pkt_pts, o->video_time_base, AV_TIME_BASE_Q);
365
    }
366
    if (o->pts0 == -1){
367
      o->pts0 = pic.pkt_pts;
368
      o->last_video_pts = pic.pkt_pts;
369
    }
370

    
371
    now = av_gettime();
372
    difft = pic.pkt_pts - o->pts0 + o->t0 + o->playout_delay - now;
373
    if (difft < 0) {
374
      o->consLate++;
375
      if (difft < o->maxDelay) {
376
        o->maxDelay = difft;
377
      }
378
    } else {
379
      o->consLate = 0;
380
      o->maxDelay = 0;
381
    }
382
    if (o->consLate >= o->cLimit) {
383
      o->playout_delay -= o->maxDelay;
384
      o->consLate = 0;
385
      o->maxDelay = 0;
386
    }
387
    if (difft >= 0) {
388
      usleep(difft);
389
    } else {
390
      return NULL;
391
    }
392
    
393
    if(o->last_video_pts <= pic.pkt_pts) {
394
      o->last_video_pts = pic.pkt_pts;
395
      height = ctx->streams[pkt.stream_index]->codec->height;
396
      width = ctx->streams[pkt.stream_index]->codec->width;
397

    
398
      if (o->swsctx == NULL) { 
399
        o->swsctx = rescaler_context(ctx->streams[pkt.stream_index]->codec);
400
        avcodec_get_frame_defaults(&rgb);
401
        avpicture_alloc((AVPicture*)&rgb, PIX_FMT_RGB24, width, height);
402
      }
403
      if (o->swsctx) {
404
        sws_scale(o->swsctx,(const uint8_t* const*) pic.data, pic.linesize, 0,
405
                  height, rgb.data, rgb.linesize);
406
   
407
        gdk_draw_rgb_image(screen, c->gc, 0, 0, width, height,
408
                           GDK_RGB_DITHER_MAX, rgb.data[0], width * 3);
409
      
410
        gtk_widget_draw(GTK_WIDGET(c->d_area), &c->u_area);
411

    
412
        return rgb.data[0];                 // FIXME!
413
      }
414
    }
415
  }
416

    
417
  return NULL;
418
}
419

    
420
static void *videothread(void *p)
421
{
422
  AVPacket pkt;
423
  struct dechunkiser_ctx *o = p;
424

    
425
  if (gtk_events_pending()) {
426
    gtk_main_iteration_do(FALSE);
427
  }
428

    
429
  for(; !o->end;) {
430
    pthread_mutex_lock(&o->lockvideo);
431
    while(o->videoq.length < 1) {
432
      pthread_cond_wait(&o->condvideo, &o->lockvideo);
433
    }
434

    
435
    if(!o->end) {
436
      pkt = dequeue(&o->videoq);
437
      pthread_mutex_unlock(&o->lockvideo);
438
      frame_display(o, pkt);
439
      av_free(pkt.data);
440
      av_free_packet(&pkt);
441
    } else {
442
      pthread_mutex_unlock(&o->lockvideo);
443
    }
444
  }
445

    
446
  while (o->videoq.length) {
447
    pkt = dequeue(&o->videoq);
448
    av_free(pkt.data);
449
    av_free_packet(&pkt);
450
  }
451

    
452
  pthread_exit(NULL);
453
}
454

    
455
static void *audiothread(void *p)
456
{
457
  AVPacket pkt;
458
  int64_t difft;
459
  int64_t now;
460
  struct dechunkiser_ctx *o = p;
461

    
462
  for(;!o->end;){
463
    pthread_mutex_lock(&o->lockaudio);
464
    while(o->audioq.length<1){
465
      pthread_cond_wait(&o->condaudio,&o->lockaudio);
466
    }
467

    
468
    if(!o->end){
469
      pkt = dequeue(&o->audioq);
470
      pthread_mutex_unlock(&o->lockaudio);
471
      now = av_gettime();
472
      difft = pkt.pts - o->pts0 + o->t0 + o->playout_delay - now;
473
      if (difft < 0) {
474
        o->consLate++;
475
        if (difft < o->maxDelay) {
476
          o->maxDelay = difft;
477
        }
478
      } else {
479
        o->consLate = 0;
480
        o->maxDelay = 0;
481
      }
482
      if (o->consLate >= o->cLimit) {
483
        o->playout_delay -= o->maxDelay;
484
        o->consLate = 0;
485
        o->maxDelay = 0;
486
      }
487
      if (difft >= 0) {
488
        usleep(difft);
489
        audio_write_packet(o, pkt);
490
      }
491
      av_free(pkt.data);
492
      av_free_packet(&pkt);
493
    } else {
494
      pthread_mutex_unlock(&o->lockaudio);
495
    }
496
  }
497

    
498
  while(o->audioq.length) {
499
    pkt = dequeue(&o->audioq);
500
    av_free(pkt.data);
501
    av_free_packet(&pkt);
502
  }
503

    
504
  pthread_exit(NULL);
505
}
506

    
507
static gint delete_event(GtkWidget *widget, GdkEvent *event, struct dechunkiser_ctx *data)
508
{
509
  data->end = 1;
510

    
511
  return TRUE;
512
}
513

    
514
static gboolean expose_event(GtkWidget *widget, GdkEventExpose *event, struct dechunkiser_ctx *data)
515
{
516
  if ((data->screen != NULL) && (!data->end)) {
517
    gdk_draw_pixmap(widget->window,
518
        widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
519
        data->screen, event->area.x, event->area.y,
520
        event->area.x, event->area.y, event->area.width,
521
        event->area.height);
522
  }
523

    
524
  return TRUE;
525
}
526

    
527
static gint configure_event(GtkWidget *widget, GdkEventConfigure *event, struct dechunkiser_ctx *data)
528
{
529
  if (!data->screen) {
530
    data->screen = gdk_pixmap_new(widget->window, widget->allocation.width,
531
                widget->allocation.height, -1);
532
    gdk_draw_rectangle(data->screen, widget->style->white_gc, TRUE, 0, 0,
533
           widget->allocation.width, widget->allocation.height);
534
  }
535
  
536
  return TRUE;
537
}
538

    
539
static void *window_prepare(struct dechunkiser_ctx *o)
540
{
541
  int w;
542
  int h;
543
  GtkWidget *vbox;
544
  GtkWidget *hbox;
545
  GtkWidget *window;
546
  GdkColor black;
547
  GdkColor white;
548
  struct controls *c;
549

    
550
  w = o->width;
551
  h = o->height;
552
  c = malloc(sizeof(struct controls));
553
  if (c == NULL) {
554
    return NULL;
555
  }
556

    
557
  gtk_widget_set_default_colormap(gdk_rgb_get_cmap());
558
  gtk_widget_set_default_visual(gdk_rgb_get_visual());
559

    
560
  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
561
  gtk_window_set_default_size(GTK_WINDOW(window), w, h );
562
  gtk_window_set_title(GTK_WINDOW(window),"Player" );
563
  vbox = gtk_vbox_new(FALSE, 0);
564
  hbox = gtk_hbox_new(FALSE, 0);
565
  gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(vbox));
566

    
567
  /* drawing area */
568
  c->d_area = gtk_drawing_area_new();
569
  gtk_drawing_area_size(GTK_DRAWING_AREA(c->d_area), w, h);
570
  gtk_signal_connect(GTK_OBJECT(c->d_area), "expose_event",
571
           GTK_SIGNAL_FUNC(expose_event),o );
572
  gtk_signal_connect(GTK_OBJECT(c->d_area), "configure_event",
573
         GTK_SIGNAL_FUNC(configure_event),o );
574
  gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(c->d_area), FALSE, FALSE, 5);
575
  gtk_widget_show(c->d_area);
576

    
577
  gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(hbox), FALSE, FALSE, 5);
578

    
579
  gtk_widget_show(hbox);
580
  gtk_widget_show(vbox);
581
  gtk_widget_show(window);
582
  gtk_signal_connect(GTK_OBJECT(window), "delete_event",
583
         GTK_SIGNAL_FUNC(delete_event),o);
584

    
585
  c->u_area.x = 0;
586
  c->u_area.y = 0;
587
  c->u_area.width = c->d_area->allocation.width;
588
  c->u_area.height = c->d_area->allocation.height;
589
  c->gc = gdk_gc_new(c->d_area->window);
590

    
591
  gdk_color_black(gdk_colormap_get_system(), &black);
592
  gdk_color_white(gdk_colormap_get_system(), &white);
593
  gdk_gc_set_foreground(c->gc, &black);
594
  gdk_gc_set_background(c->gc, &white);
595

    
596
  return c;
597
}
598

    
599
static AVFormatContext *format_init(struct dechunkiser_ctx * o)
600
{
601
  AVFormatContext *of;
602
  AVOutputFormat *outfmt;
603
  
604
  av_register_all();
605

    
606
  outfmt = av_guess_format("null", NULL, NULL);
607
  of = avformat_alloc_context();
608
  if (of == NULL) {
609
    return NULL;
610
  }
611
  of->oformat = outfmt;
612

    
613
  return of;
614
}
615

    
616
static AVFormatContext *format_gen(struct dechunkiser_ctx *o, const uint8_t *data)
617
{
618
  uint8_t codec;
619

    
620
  codec = data[0];
621
  if ((codec < 128) && ((o->streams & 0x01) == 0)) {
622
    int width, height, frame_rate_n, frame_rate_d;
623

    
624
    o->streams |= 0x01;
625
    o->video_codec_id = libav_codec_id(codec);
626
    video_payload_header_parse(data, &codec, &width, &height, &frame_rate_n, &frame_rate_d);
627
    o->width = width;
628
    o->height= height;
629
    o->video_time_base.den = frame_rate_n;
630
    o->video_time_base.num = frame_rate_d;
631
  } else if ((codec > 128) && ((o->streams & 0x02) == 0)) {
632
    uint8_t channels;
633
    int sample_rate, frame_size;
634

    
635
    audio_payload_header_parse(data, &codec, &channels, &sample_rate, &frame_size);
636
    o->streams |= 0x02;
637
    o->audio_codec_id = libav_codec_id(codec);
638
    o->sample_rate = sample_rate;
639
    o->channels = channels;
640
    o->frame_size = frame_size;
641
    o->audio_time_base.num = frame_size;
642
    o->audio_time_base.den = sample_rate;
643
  }
644

    
645
  if (o->streams == o->selected_streams) {
646
    AVCodecContext *c;
647

    
648
    o->outctx = format_init(o);
649
    if (o->streams & 0x01) {
650
      AVCodec *vCodec;
651

    
652
      av_new_stream(o->outctx, 0);
653
      c = o->outctx->streams[o->outctx->nb_streams - 1]->codec;
654
      c->codec_id = o->video_codec_id;
655
      c->codec_type = CODEC_TYPE_VIDEO;
656
      c->width = o->width;
657
      c->height= o->height;
658
      c->time_base.den = o->video_time_base.den;
659
      c->time_base.num = o->video_time_base.num;
660
      o->outctx->streams[0]->avg_frame_rate.num = o->video_time_base.den;
661
      o->outctx->streams[0]->avg_frame_rate.den = o->video_time_base.num;
662

    
663
      c->pix_fmt = PIX_FMT_YUV420P;
664
      vCodec = avcodec_find_decoder(o->outctx->streams[o->outctx->nb_streams - 1]->codec->codec_id);
665
      if(!vCodec) {
666
       fprintf(stderr, "Video unsupported codec\n");
667

    
668
       return NULL;
669
      }
670
      if(avcodec_open(o->outctx->streams[o->outctx->nb_streams - 1]->codec, vCodec)<0){
671
        fprintf(stderr, "could not open video codec\n");
672

    
673
        return NULL; // Could not open codec
674
      }
675
      o->c1 = window_prepare(o);
676
    }
677

    
678
    if (o->streams & 0x02) {
679
      AVCodec  *aCodec;
680

    
681
      av_new_stream(o->outctx, 1);
682
      c = o->outctx->streams[o->outctx->nb_streams - 1]->codec;
683
      c->codec_id = o->audio_codec_id;
684
      c->codec_type = CODEC_TYPE_AUDIO;
685
      c->sample_rate = o->sample_rate;
686
      c->channels = o->channels;
687
      c->frame_size = o->frame_size;
688
      c->time_base.num = o->audio_time_base.num;
689
      c->time_base.den = o->audio_time_base.den;
690

    
691
      aCodec = avcodec_find_decoder(o->outctx->streams[o->outctx->nb_streams - 1]->codec->codec_id);
692
      if(!aCodec) {
693
        fprintf(stderr, "Audio unsupported codec\n");
694

    
695
        return NULL;
696
      }
697
      if (avcodec_open(o->outctx->streams[o->outctx->nb_streams - 1]->codec, aCodec)<0) {
698
        fprintf (stderr, "could not open audio codec\n");
699

    
700
        return NULL; // Could not open codec
701
      }
702
    }
703

    
704
    o->prev_pts = 0;
705
    o->prev_dts = 0;
706

    
707
    return o->outctx;
708
  }
709

    
710
  return NULL;
711
}
712

    
713
static struct dechunkiser_ctx *play_init(const char * fname, const char * config)
714
{
715
  struct dechunkiser_ctx *out;
716
  struct tag *cfg_tags;
717

    
718
  out = malloc(sizeof(struct dechunkiser_ctx));
719
  if (out == NULL) {
720
    return NULL;
721
  }
722

    
723
  memset(out, 0, sizeof(struct dechunkiser_ctx));
724
  out->selected_streams = 0x01;
725
  cfg_tags = config_parse(config);
726
  if (cfg_tags) {
727
    const char *format;
728

    
729
    format = config_value_str(cfg_tags, "media");
730
    if (format) {
731
      if (!strcmp(format, "video")) {
732
        out->selected_streams = 0x01;
733
      } else if (!strcmp(format, "audio")) {
734
        out->selected_streams = 0x02;
735
      } else if (!strcmp(format, "av")) {
736
        out->selected_streams = 0x03;
737
      }
738
    }
739
  }
740
  free(cfg_tags); 
741

    
742
  out->playout_delay = 1000000;
743
  out->pts0 = -1;
744
  out->cLimit = 30;
745
  out->device_name = "hw:0";
746

    
747
  gtk_init(NULL, NULL);
748
  //gdk_rgb_init();
749
  pthread_mutex_init(&out->lockvideo, NULL);
750
  pthread_cond_init(&out->condvideo, NULL);
751
  pthread_mutex_init(&out->lockaudio, NULL);
752
  pthread_cond_init(&out->condaudio, NULL);
753
  pthread_create(&out->tid_video, NULL, videothread, out);
754
  pthread_create(&out->tid_audio, NULL, audiothread, out);
755

    
756
  return out;
757
}
758

    
759
static void play_write(struct dechunkiser_ctx *o, int id, uint8_t *data, int size)
760
{
761
  int header_size;
762
  int frames, i, media_type;
763
  uint8_t *p;
764

    
765
  if (data[0] == 0) {
766
    fprintf(stderr, "Error! strange chunk: %x!!!\n", data[0]);
767
    return;
768
  } else if (data[0] < 127) {
769
    header_size = VIDEO_PAYLOAD_HEADER_SIZE;
770
    media_type = 1;
771
  } else {
772
    header_size = AUDIO_PAYLOAD_HEADER_SIZE;
773
    media_type = 2;
774
  }
775

    
776
  if (o->outctx == NULL) { 
777
    o->outctx = format_gen(o, data);
778
    if (o->outctx == NULL) {    
779
      fprintf(stderr, "Format init failed\n");
780
      return;
781
    }
782
    
783
    if(o->t0 == 0){
784
      o->t0 = av_gettime();
785
    }
786
    av_set_parameters(o->outctx, NULL);
787
    dump_format(o->outctx, 0, "", 1);
788
  }
789
  if ((o->streams & media_type) == 0) {
790
    return;    /* Received a chunk for a non-selected stream */
791
  }
792

    
793
  frames = data[header_size - 1];
794
  p = data + header_size + FRAME_HEADER_SIZE * frames;
795
  for (i = 0; i < frames; i++) { 
796
    AVPacket pkt;
797
    int64_t pts, dts;
798
    int frame_size;
799

    
800
    frame_header_parse(data + header_size + FRAME_HEADER_SIZE * i,
801
                       &frame_size, &pts, &dts);
802

    
803
    //dprintf("Frame %d PTS1: %d\n", i, pts);
804
    av_init_packet(&pkt);
805

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

    
808
    if (pts != -1) {
809
      pts += (pts < o->prev_pts - ((1LL << 31) - 1)) ? ((o->prev_pts >> 32) + 1) << 32 : (o->prev_pts >> 32) << 32;
810
      o->prev_pts = pts;
811
      pkt.pts = pts;
812
    } else {
813
      pkt.pts = AV_NOPTS_VALUE;
814
    }
815
    dts += (dts < o->prev_dts - ((1LL << 31) - 1)) ? ((o->prev_dts >> 32) + 1) << 32 : (o->prev_dts >> 32) << 32;
816
    o->prev_dts = dts;
817
    pkt.dts = dts;
818
    // pkt.data = p;
819
    pkt.data = av_mallocz(frame_size + FF_INPUT_BUFFER_PADDING_SIZE);
820
    memcpy(pkt.data, p, frame_size);
821
    p += frame_size;
822
    pkt.size = frame_size;
823

    
824
    if (pkt.stream_index == 0) {
825
      pthread_mutex_lock(&o->lockvideo);
826
      enqueue(&o->videoq, pkt);
827
      pthread_cond_signal(&o->condvideo);
828
      pthread_mutex_unlock(&o->lockvideo);
829
    } else {
830
        /* FIXME: Why is this pts handling and rescaling here? */
831
      if (o->pts0 == -1) {
832
        o->pts0 = av_rescale_q(pkt.pts, o->audio_time_base, AV_TIME_BASE_Q);
833
      }
834

    
835
      pkt.pts = av_rescale_q(pkt.pts, o->audio_time_base, AV_TIME_BASE_Q);
836

    
837
      pthread_mutex_lock(&o->lockaudio);
838
      enqueue(&o->audioq, pkt);
839
      pthread_cond_signal(&o->condaudio);
840
      pthread_mutex_unlock(&o->lockaudio);
841
    }
842
  }
843
}
844

    
845
static void play_close(struct dechunkiser_ctx *s)
846
{
847
  int i;
848

    
849
  s->end = 1;
850
  pthread_cond_signal(&s->condaudio);
851
  pthread_cond_signal(&s->condvideo);
852
  pthread_join(s->tid_video, NULL);
853
  pthread_join(s->tid_audio, NULL);
854
  pthread_cond_destroy(&s->condvideo);
855
  pthread_mutex_destroy(&s->lockvideo);
856
  pthread_cond_destroy(&s->condaudio);
857
  pthread_mutex_destroy(&s->lockaudio);
858

    
859
  if (s->playback_handle) {
860
    snd_pcm_close (s->playback_handle);
861
  }
862
  if (s->rsc) {
863
    audio_resample_close(s->rsc);
864
  }
865
 
866
  for (i = 0; i < s->outctx->nb_streams; i++) {
867
    avcodec_close(s->outctx->streams[i]->codec);
868
    av_metadata_free(&s->outctx->streams[i]->metadata);
869
    av_free(s->outctx->streams[i]->codec);
870
    av_free(s->outctx->streams[i]->info);
871
    av_free(s->outctx->streams[i]);
872
  }
873
  av_metadata_free(&s->outctx->metadata);
874
  free(s->outctx);
875
  //tobefreed c1->d_area, c1->gc
876
  //gtk_widget_destroy(window);
877
  if (s->swsctx) {
878
    sws_freeContext(s->swsctx);
879
  }
880
  free(s->c1);
881
  free(s);
882
}
883

    
884
struct dechunkiser_iface out_play = {
885
  .open = play_init,
886
  .write = play_write,
887
  .close = play_close,
888
};