Statistics
| Branch: | Revision:

grapes / src / Chunkiser / output-stream-play.c @ 176b8de8

History | View | Annotate | Download (22.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 "grapes_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_near(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->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
static int64_t synchronise(struct dechunkiser_ctx *o, int64_t pts)
342
{
343
  int64_t now, difft;
344

    
345
  now = av_gettime();
346
  difft = pts - o->pts0 + o->t0 + o->playout_delay - now;
347
  if (difft < 0) {
348
    o->consLate++;
349
    if (difft < o->maxDelay) {
350
      o->maxDelay = difft;
351
    }
352
  } else {
353
    o->consLate = 0;
354
    o->maxDelay = 0;
355
  }
356
  if (o->consLate >= o->cLimit) {
357
    o->playout_delay -= o->maxDelay;
358
    o->consLate = 0;
359
    o->maxDelay = 0;
360
  }
361
  if (difft >= 0) {
362
    usleep(difft);
363
  }
364

    
365
  return difft;
366
}
367

    
368
/* FIXME: Return value??? What is it used for? */
369
static uint8_t *frame_display(struct dechunkiser_ctx *o, AVPacket pkt)
370
{ 
371
  GdkPixmap *screen = o->screen;
372
  AVFormatContext *ctx = o->outctx;
373
  int res = 1, decoded, height, width;
374
  AVFrame pic;
375
  static AVFrame rgb;
376
  struct controls *c = o->c1;
377

    
378
  avcodec_get_frame_defaults(&pic);
379
  pic.pkt_pts = pkt.dts;
380
  res = avcodec_decode_video2(ctx->streams[pkt.stream_index]->codec, &pic, &decoded, &pkt);
381
  if (res < 0) {
382
    return NULL;
383
  }
384

    
385
  if (decoded) {
386
    if(AV_NOPTS_VALUE == pic.pkt_pts) {
387
      pic.pkt_pts = av_rescale_q(pkt.dts, o->video_time_base, AV_TIME_BASE_Q);
388
    } else {
389
      pic.pkt_pts = av_rescale_q(pic.pkt_pts, o->video_time_base, AV_TIME_BASE_Q);
390
    }
391
    if (o->pts0 == -1){
392
      o->pts0 = pic.pkt_pts;
393
      o->last_video_pts = pic.pkt_pts;
394
    }
395

    
396
    if (synchronise(o, pic.pkt_pts) < 0) {
397
      return NULL;
398
    }
399
    
400
    if(o->last_video_pts <= pic.pkt_pts) {
401
      o->last_video_pts = pic.pkt_pts;
402
      height = ctx->streams[pkt.stream_index]->codec->height;
403
      width = ctx->streams[pkt.stream_index]->codec->width;
404

    
405
      if (o->swsctx == NULL) { 
406
        o->swsctx = rescaler_context(ctx->streams[pkt.stream_index]->codec);
407
        avcodec_get_frame_defaults(&rgb);
408
        avpicture_alloc((AVPicture*)&rgb, PIX_FMT_RGB24, width, height);
409
      }
410
      if (o->swsctx) {
411
        sws_scale(o->swsctx,(const uint8_t* const*) pic.data, pic.linesize, 0,
412
                  height, rgb.data, rgb.linesize);
413
   
414
        gdk_draw_rgb_image(screen, c->gc, 0, 0, width, height,
415
                           GDK_RGB_DITHER_MAX, rgb.data[0], width * 3);
416
      
417
        gtk_widget_draw(GTK_WIDGET(c->d_area), &c->u_area);
418

    
419
        return rgb.data[0];                 // FIXME!
420
      }
421
    }
422
  }
423

    
424
  return NULL;
425
}
426

    
427
static void *videothread(void *p)
428
{
429
  AVPacket pkt;
430
  struct dechunkiser_ctx *o = p;
431

    
432
  if (gtk_events_pending()) {
433
    gtk_main_iteration_do(FALSE);
434
  }
435

    
436
  for(; !o->end;) {
437
    pthread_mutex_lock(&o->lockvideo);
438
    while(o->videoq.length < 1) {
439
      pthread_cond_wait(&o->condvideo, &o->lockvideo);
440
    }
441

    
442
    if(!o->end) {
443
      pkt = dequeue(&o->videoq);
444
      pthread_mutex_unlock(&o->lockvideo);
445
      frame_display(o, pkt);
446
      av_free(pkt.data);
447
      av_free_packet(&pkt);
448
    } else {
449
      pthread_mutex_unlock(&o->lockvideo);
450
    }
451
  }
452

    
453
  while (o->videoq.length) {
454
    pkt = dequeue(&o->videoq);
455
    av_free(pkt.data);
456
    av_free_packet(&pkt);
457
  }
458

    
459
  pthread_exit(NULL);
460
}
461

    
462
static void *audiothread(void *p)
463
{
464
  AVPacket pkt;
465
  struct dechunkiser_ctx *o = p;
466

    
467
  for(;!o->end;){
468
    pthread_mutex_lock(&o->lockaudio);
469
    while(o->audioq.length<1){
470
      pthread_cond_wait(&o->condaudio,&o->lockaudio);
471
    }
472

    
473
    if(!o->end){
474
      pkt = dequeue(&o->audioq);
475
      pthread_mutex_unlock(&o->lockaudio);
476
      pkt.pts = av_rescale_q(pkt.pts, o->audio_time_base, AV_TIME_BASE_Q);
477
      if (o->pts0 == -1) {
478
        o->pts0 = pkt.pts;
479
      }
480

    
481
      if (synchronise(o, pkt.pts) >= 0) {
482
        audio_write_packet(o, pkt);
483
      }
484
      av_free(pkt.data);
485
      av_free_packet(&pkt);
486
    } else {
487
      pthread_mutex_unlock(&o->lockaudio);
488
    }
489
  }
490

    
491
  while(o->audioq.length) {
492
    pkt = dequeue(&o->audioq);
493
    av_free(pkt.data);
494
    av_free_packet(&pkt);
495
  }
496

    
497
  pthread_exit(NULL);
498
}
499

    
500
static gint delete_event(GtkWidget *widget, GdkEvent *event, struct dechunkiser_ctx *data)
501
{
502
  data->end = 1;
503

    
504
  return TRUE;
505
}
506

    
507
static gboolean expose_event(GtkWidget *widget, GdkEventExpose *event, struct dechunkiser_ctx *data)
508
{
509
  if ((data->screen != NULL) && (!data->end)) {
510
    gdk_draw_pixmap(widget->window,
511
        widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
512
        data->screen, event->area.x, event->area.y,
513
        event->area.x, event->area.y, event->area.width,
514
        event->area.height);
515
  }
516

    
517
  return TRUE;
518
}
519

    
520
static gint configure_event(GtkWidget *widget, GdkEventConfigure *event, struct dechunkiser_ctx *data)
521
{
522
  if (!data->screen) {
523
    data->screen = gdk_pixmap_new(widget->window, widget->allocation.width,
524
                widget->allocation.height, -1);
525
    gdk_draw_rectangle(data->screen, widget->style->white_gc, TRUE, 0, 0,
526
           widget->allocation.width, widget->allocation.height);
527
  }
528
  
529
  return TRUE;
530
}
531

    
532
static void *window_prepare(struct dechunkiser_ctx *o)
533
{
534
  int w;
535
  int h;
536
  GtkWidget *vbox;
537
  GtkWidget *hbox;
538
  GtkWidget *window;
539
  GdkColor black;
540
  GdkColor white;
541
  struct controls *c;
542

    
543
  w = o->width;
544
  h = o->height;
545
  c = malloc(sizeof(struct controls));
546
  if (c == NULL) {
547
    return NULL;
548
  }
549

    
550
  gtk_widget_set_default_colormap(gdk_rgb_get_cmap());
551
  gtk_widget_set_default_visual(gdk_rgb_get_visual());
552

    
553
  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
554
  gtk_window_set_default_size(GTK_WINDOW(window), w, h );
555
  gtk_window_set_title(GTK_WINDOW(window),"Player" );
556
  vbox = gtk_vbox_new(FALSE, 0);
557
  hbox = gtk_hbox_new(FALSE, 0);
558
  gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(vbox));
559

    
560
  /* drawing area */
561
  c->d_area = gtk_drawing_area_new();
562
  gtk_drawing_area_size(GTK_DRAWING_AREA(c->d_area), w, h);
563
  gtk_signal_connect(GTK_OBJECT(c->d_area), "expose_event",
564
           GTK_SIGNAL_FUNC(expose_event),o );
565
  gtk_signal_connect(GTK_OBJECT(c->d_area), "configure_event",
566
         GTK_SIGNAL_FUNC(configure_event),o );
567
  gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(c->d_area), FALSE, FALSE, 5);
568
  gtk_widget_show(c->d_area);
569

    
570
  gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(hbox), FALSE, FALSE, 5);
571

    
572
  gtk_widget_show(hbox);
573
  gtk_widget_show(vbox);
574
  gtk_widget_show(window);
575
  gtk_signal_connect(GTK_OBJECT(window), "delete_event",
576
         GTK_SIGNAL_FUNC(delete_event),o);
577

    
578
  c->u_area.x = 0;
579
  c->u_area.y = 0;
580
  c->u_area.width = c->d_area->allocation.width;
581
  c->u_area.height = c->d_area->allocation.height;
582
  c->gc = gdk_gc_new(c->d_area->window);
583

    
584
  gdk_color_black(gdk_colormap_get_system(), &black);
585
  gdk_color_white(gdk_colormap_get_system(), &white);
586
  gdk_gc_set_foreground(c->gc, &black);
587
  gdk_gc_set_background(c->gc, &white);
588

    
589
  return c;
590
}
591

    
592
static AVFormatContext *format_init(struct dechunkiser_ctx * o)
593
{
594
  AVFormatContext *of;
595
  AVOutputFormat *outfmt;
596
  
597
  av_register_all();
598

    
599
  outfmt = av_guess_format("null", NULL, NULL);
600
  of = avformat_alloc_context();
601
  if (of == NULL) {
602
    return NULL;
603
  }
604
  of->oformat = outfmt;
605

    
606
  return of;
607
}
608

    
609
static AVFormatContext *format_gen(struct dechunkiser_ctx *o, const uint8_t *data)
610
{
611
  uint8_t codec;
612

    
613
  codec = data[0];
614
  if ((codec < 128) && ((o->streams & 0x01) == 0)) {
615
    int width, height, frame_rate_n, frame_rate_d;
616

    
617
    o->streams |= 0x01;
618
    o->video_codec_id = libav_codec_id(codec);
619
    video_payload_header_parse(data, &codec, &width, &height, &frame_rate_n, &frame_rate_d);
620
    o->width = width;
621
    o->height= height;
622
    o->video_time_base.den = frame_rate_n;
623
    o->video_time_base.num = frame_rate_d;
624
  } else if ((codec > 128) && ((o->streams & 0x02) == 0)) {
625
    uint8_t channels;
626
    int sample_rate, frame_size;
627

    
628
    audio_payload_header_parse(data, &codec, &channels, &sample_rate, &frame_size);
629
    o->streams |= 0x02;
630
    o->audio_codec_id = libav_codec_id(codec);
631
    o->sample_rate = sample_rate;
632
    o->channels = channels;
633
    o->frame_size = frame_size;
634
    o->audio_time_base.num = frame_size;
635
    o->audio_time_base.den = sample_rate;
636
  }
637

    
638
  if (o->streams == o->selected_streams) {
639
    AVCodecContext *c;
640

    
641
    o->outctx = format_init(o);
642
    if (o->streams & 0x01) {
643
      AVCodec *vCodec;
644

    
645
      av_new_stream(o->outctx, 0);
646
      c = o->outctx->streams[o->outctx->nb_streams - 1]->codec;
647
      c->codec_id = o->video_codec_id;
648
      c->codec_type = CODEC_TYPE_VIDEO;
649
      c->width = o->width;
650
      c->height= o->height;
651
      c->time_base.den = o->video_time_base.den;
652
      c->time_base.num = o->video_time_base.num;
653
      o->outctx->streams[0]->avg_frame_rate.num = o->video_time_base.den;
654
      o->outctx->streams[0]->avg_frame_rate.den = o->video_time_base.num;
655

    
656
      c->pix_fmt = PIX_FMT_YUV420P;
657
      vCodec = avcodec_find_decoder(o->outctx->streams[o->outctx->nb_streams - 1]->codec->codec_id);
658
      if(!vCodec) {
659
       fprintf(stderr, "Video unsupported codec\n");
660

    
661
       return NULL;
662
      }
663
      if(avcodec_open(o->outctx->streams[o->outctx->nb_streams - 1]->codec, vCodec)<0){
664
        fprintf(stderr, "could not open video codec\n");
665

    
666
        return NULL; // Could not open codec
667
      }
668
      o->c1 = window_prepare(o);
669
    }
670

    
671
    if (o->streams & 0x02) {
672
      AVCodec  *aCodec;
673

    
674
      av_new_stream(o->outctx, 1);
675
      c = o->outctx->streams[o->outctx->nb_streams - 1]->codec;
676
      c->codec_id = o->audio_codec_id;
677
      c->codec_type = CODEC_TYPE_AUDIO;
678
      c->sample_rate = o->sample_rate;
679
      c->channels = o->channels;
680
      c->frame_size = o->frame_size;
681
      c->time_base.num = o->audio_time_base.num;
682
      c->time_base.den = o->audio_time_base.den;
683

    
684
      aCodec = avcodec_find_decoder(o->outctx->streams[o->outctx->nb_streams - 1]->codec->codec_id);
685
      if(!aCodec) {
686
        fprintf(stderr, "Audio unsupported codec\n");
687

    
688
        return NULL;
689
      }
690
      if (avcodec_open(o->outctx->streams[o->outctx->nb_streams - 1]->codec, aCodec)<0) {
691
        fprintf (stderr, "could not open audio codec\n");
692

    
693
        return NULL; // Could not open codec
694
      }
695
    }
696

    
697
    o->prev_pts = 0;
698
    o->prev_dts = 0;
699

    
700
    return o->outctx;
701
  }
702

    
703
  return NULL;
704
}
705

    
706
static struct dechunkiser_ctx *play_init(const char * fname, const char * config)
707
{
708
  struct dechunkiser_ctx *out;
709
  struct tag *cfg_tags;
710

    
711
  out = malloc(sizeof(struct dechunkiser_ctx));
712
  if (out == NULL) {
713
    return NULL;
714
  }
715

    
716
  memset(out, 0, sizeof(struct dechunkiser_ctx));
717
  out->selected_streams = 0x01;
718
  cfg_tags = grapes_config_parse(config);
719
  if (cfg_tags) {
720
    const char *format;
721

    
722
    format = grapes_config_value_str(cfg_tags, "media");
723
    if (format) {
724
      if (!strcmp(format, "video")) {
725
        out->selected_streams = 0x01;
726
      } else if (!strcmp(format, "audio")) {
727
        out->selected_streams = 0x02;
728
      } else if (!strcmp(format, "av")) {
729
        out->selected_streams = 0x03;
730
      }
731
    }
732
  }
733
  free(cfg_tags); 
734

    
735
  out->playout_delay = 1000000;
736
  out->pts0 = -1;
737
  out->cLimit = 30;
738
  out->device_name = "hw:0";
739

    
740
  gtk_init(NULL, NULL);
741
  //gdk_rgb_init();
742
  pthread_mutex_init(&out->lockvideo, NULL);
743
  pthread_cond_init(&out->condvideo, NULL);
744
  pthread_mutex_init(&out->lockaudio, NULL);
745
  pthread_cond_init(&out->condaudio, NULL);
746
  pthread_create(&out->tid_video, NULL, videothread, out);
747
  pthread_create(&out->tid_audio, NULL, audiothread, out);
748

    
749
  return out;
750
}
751

    
752
static void play_write(struct dechunkiser_ctx *o, int id, uint8_t *data, int size)
753
{
754
  int header_size;
755
  int frames, i, media_type;
756
  uint8_t *p;
757

    
758
  if (data[0] == 0) {
759
    fprintf(stderr, "Error! strange chunk: %x!!!\n", data[0]);
760
    return;
761
  } else if (data[0] < 127) {
762
    header_size = VIDEO_PAYLOAD_HEADER_SIZE;
763
    media_type = 1;
764
  } else {
765
    header_size = AUDIO_PAYLOAD_HEADER_SIZE;
766
    media_type = 2;
767
  }
768

    
769
  if (o->outctx == NULL) { 
770
    o->outctx = format_gen(o, data);
771
    if (o->outctx == NULL) {    
772
      fprintf(stderr, "Format init failed\n");
773
      return;
774
    }
775
    
776
    if(o->t0 == 0){
777
      o->t0 = av_gettime();
778
    }
779
    av_set_parameters(o->outctx, NULL);
780
    dump_format(o->outctx, 0, "", 1);
781
  }
782
  if ((o->streams & media_type) == 0) {
783
    return;    /* Received a chunk for a non-selected stream */
784
  }
785

    
786
  frames = data[header_size - 1];
787
  p = data + header_size + FRAME_HEADER_SIZE * frames;
788
  for (i = 0; i < frames; i++) { 
789
    AVPacket pkt;
790
    int64_t pts, dts;
791
    int frame_size;
792

    
793
    frame_header_parse(data + header_size + FRAME_HEADER_SIZE * i,
794
                       &frame_size, &pts, &dts);
795

    
796
    //dprintf("Frame %d PTS1: %d\n", i, pts);
797
    av_init_packet(&pkt);
798

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

    
801
    if (pts != -1) {
802
      pts += (pts < o->prev_pts - ((1LL << 31) - 1)) ? ((o->prev_pts >> 32) + 1) << 32 : (o->prev_pts >> 32) << 32;
803
      o->prev_pts = pts;
804
      pkt.pts = pts;
805
    } else {
806
      pkt.pts = AV_NOPTS_VALUE;
807
    }
808
    dts += (dts < o->prev_dts - ((1LL << 31) - 1)) ? ((o->prev_dts >> 32) + 1) << 32 : (o->prev_dts >> 32) << 32;
809
    o->prev_dts = dts;
810
    pkt.dts = dts;
811
    // pkt.data = p;
812
    pkt.data = av_mallocz(frame_size + FF_INPUT_BUFFER_PADDING_SIZE);
813
    memcpy(pkt.data, p, frame_size);
814
    p += frame_size;
815
    pkt.size = frame_size;
816

    
817
    if (pkt.stream_index == 0) {
818
      pthread_mutex_lock(&o->lockvideo);
819
      enqueue(&o->videoq, pkt);
820
      pthread_cond_signal(&o->condvideo);
821
      pthread_mutex_unlock(&o->lockvideo);
822
    } else {
823
      pthread_mutex_lock(&o->lockaudio);
824
      enqueue(&o->audioq, pkt);
825
      pthread_cond_signal(&o->condaudio);
826
      pthread_mutex_unlock(&o->lockaudio);
827
    }
828
  }
829
}
830

    
831
static void play_close(struct dechunkiser_ctx *s)
832
{
833
  int i;
834

    
835
  s->end = 1;
836
  pthread_cond_signal(&s->condaudio);
837
  pthread_cond_signal(&s->condvideo);
838
  pthread_join(s->tid_video, NULL);
839
  pthread_join(s->tid_audio, NULL);
840
  pthread_cond_destroy(&s->condvideo);
841
  pthread_mutex_destroy(&s->lockvideo);
842
  pthread_cond_destroy(&s->condaudio);
843
  pthread_mutex_destroy(&s->lockaudio);
844

    
845
  if (s->playback_handle) {
846
    snd_pcm_close (s->playback_handle);
847
  }
848
  if (s->rsc) {
849
    audio_resample_close(s->rsc);
850
  }
851
 
852
  for (i = 0; i < s->outctx->nb_streams; i++) {
853
    avcodec_close(s->outctx->streams[i]->codec);
854
    av_metadata_free(&s->outctx->streams[i]->metadata);
855
    av_free(s->outctx->streams[i]->codec);
856
    av_free(s->outctx->streams[i]->info);
857
    av_free(s->outctx->streams[i]);
858
  }
859
  av_metadata_free(&s->outctx->metadata);
860
  free(s->outctx);
861
  //tobefreed c1->d_area, c1->gc
862
  //gtk_widget_destroy(window);
863
  if (s->swsctx) {
864
    sws_freeContext(s->swsctx);
865
  }
866
  free(s->c1);
867
  free(s);
868
}
869

    
870
struct dechunkiser_iface out_play = {
871
  .open = play_init,
872
  .write = play_write,
873
  .close = play_close,
874
};