Statistics
| Branch: | Revision:

grapes / src / Chunkiser / input-stream-avf.c @ 997c2b68

History | View | Annotate | Download (10.7 KB)

1 1e8dedd8 Luca Abeni
/*
2
 *  Copyright (c) 2009 Luca Abeni
3
 *
4
 *  This is free software; see gpl-3.0.txt
5
 */
6
7
#include <libavformat/avformat.h>
8
#include <stdbool.h>
9 0f79759c Luca Abeni
#include <string.h>
10 1e8dedd8 Luca Abeni
11
//#include "dbg.h"
12 0f79759c Luca Abeni
#include "int_coding.h"
13 1e8dedd8 Luca Abeni
#include "payload.h"
14
#include "config.h"
15 c0c735aa Luca Abeni
#include "chunkiser_iface.h"
16 1e8dedd8 Luca Abeni
17
#define STATIC_BUFF_SIZE 1000 * 1024
18 fcc01ba5 Luca Abeni
struct chunkiser_ctx {
19 1e8dedd8 Luca Abeni
  AVFormatContext *s;
20 1cc19859 Luca Abeni
  int loop;        //loop on input file infinitely
21 025da5a8 Luca Abeni
  uint64_t streams;
22 1e8dedd8 Luca Abeni
  int64_t last_ts;
23
  int64_t base_ts;
24 a6497b4b Luca Abeni
  AVBitStreamFilterContext *bsf[MAX_STREAMS];
25 1e8dedd8 Luca Abeni
};
26
27
static uint8_t codec_type(enum CodecID cid)
28
{
29
  switch (cid) {
30
    case CODEC_ID_MPEG1VIDEO:
31
    case CODEC_ID_MPEG2VIDEO:
32
      return 1;
33
    case CODEC_ID_H261:
34
      return 2;
35
    case CODEC_ID_H263P:
36
    case CODEC_ID_H263:
37
      return 3;
38
    case CODEC_ID_MJPEG:
39
      return 4;
40
    case CODEC_ID_MPEG4:
41
      return 5;
42
    case CODEC_ID_FLV1:
43
      return 6;
44
    case CODEC_ID_SVQ3:
45
      return 7;
46
    case CODEC_ID_DVVIDEO:
47
      return 8;
48
    case CODEC_ID_H264:
49
      return 9;
50
    case CODEC_ID_THEORA:
51
    case CODEC_ID_VP3:
52
      return 10;
53
    case CODEC_ID_SNOW:
54
      return 11;
55
    case CODEC_ID_VP6:
56
      return 12;
57
    case CODEC_ID_DIRAC:
58
      return 13;
59 28e6b134 Luca Abeni
    case CODEC_ID_MP2:
60
    case CODEC_ID_MP3:
61
      return 129;
62
    case CODEC_ID_AAC:
63
      return 130;
64
    case CODEC_ID_AC3:
65
      return 131;
66
    case CODEC_ID_VORBIS:
67
      return 132;
68 1e8dedd8 Luca Abeni
    default:
69
      fprintf(stderr, "Unknown codec ID %d\n", cid);
70
      return 0;
71
  }
72
}
73
74 52f45fc1 Luca Abeni
static void audio_header_fill(uint8_t *data, AVStream *st)
75
{
76
  audio_payload_header_write(data, codec_type(st->codec->codec_id), st->codec->channels, st->codec->sample_rate, st->codec->frame_size);
77
}
78
79 1e8dedd8 Luca Abeni
static void video_header_fill(uint8_t *data, AVStream *st)
80
{
81
  int num, den;
82
83
  num = st->avg_frame_rate.num;
84
  den = st->avg_frame_rate.den;
85
//fprintf(stderr, "Rate: %d/%d\n", num, den);
86
  if (num == 0) {
87
    num = st->r_frame_rate.num;
88
    den = st->r_frame_rate.den;
89
  }
90
  if (num > (1 << 16)) {
91
    num /= 1000;
92
    den /= 1000;
93
  }
94 09154f88 Luca Abeni
  video_payload_header_write(data, codec_type(st->codec->codec_id), st->codec->width, st->codec->height, num, den);
95 1e8dedd8 Luca Abeni
}
96
97 fb2411d6 Luca Abeni
static void frame_header_fill(uint8_t *data, int size, AVPacket *pkt, AVStream *st, AVRational new_tb, int64_t base_ts)
98 1e8dedd8 Luca Abeni
{
99
  int32_t pts, dts;
100
101
  if (pkt->pts != AV_NOPTS_VALUE) {
102 7e44761d Luca Abeni
    pts = av_rescale_q(pkt->pts, st->time_base, new_tb),
103
    pts += av_rescale_q(base_ts, AV_TIME_BASE_Q, new_tb);
104 1e8dedd8 Luca Abeni
  } else {
105
    pts = -1;
106
  }
107
  //dprintf("pkt->pts=%ld PTS=%d",pkt->pts, pts);
108
  if (pkt->dts != AV_NOPTS_VALUE) {
109 7e44761d Luca Abeni
    dts = av_rescale_q(pkt->dts, st->time_base, new_tb);
110
    dts += av_rescale_q(base_ts, AV_TIME_BASE_Q, new_tb);
111 1e8dedd8 Luca Abeni
  } else {
112
    fprintf(stderr, "No DTS???\n");
113
    dts = 0;
114
  }
115
  //dprintf(" DTS=%d\n",dts);
116
  frame_header_write(data, size, pts, dts);
117
}
118
119 fcc01ba5 Luca Abeni
static int input_stream_rewind(struct chunkiser_ctx *s)
120 c0c735aa Luca Abeni
{
121 851db83d Luca Abeni
  int ret;
122 c0c735aa Luca Abeni
123 851db83d Luca Abeni
  ret = av_seek_frame(s->s,-1,0,0);
124
  s->base_ts = s->last_ts;
125 c0c735aa Luca Abeni
126 851db83d Luca Abeni
  return ret;
127 c0c735aa Luca Abeni
}
128
129
130
/* Interface functions */
131
132 fcc01ba5 Luca Abeni
static struct chunkiser_ctx *avf_open(const char *fname, int *period, const char *config)
133 1e8dedd8 Luca Abeni
{
134 fcc01ba5 Luca Abeni
  struct chunkiser_ctx *desc;
135 1e8dedd8 Luca Abeni
  int i, res;
136 1cc19859 Luca Abeni
  struct tag *cfg_tags;
137 025da5a8 Luca Abeni
  int video_streams = 0, audio_streams = 1;
138 1e8dedd8 Luca Abeni
139
  avcodec_register_all();
140
  av_register_all();
141
142 fcc01ba5 Luca Abeni
  desc = malloc(sizeof(struct chunkiser_ctx));
143 1e8dedd8 Luca Abeni
  if (desc == NULL) {
144
    return NULL;
145
  }
146
  res = av_open_input_file(&desc->s, fname, NULL, 0, NULL);
147
  if (res < 0) {
148
    fprintf(stderr, "Error opening %s: %d\n", fname, res);
149
150
    return NULL;
151
  }
152
153
  desc->s->flags |= AVFMT_FLAG_GENPTS;
154
  res = av_find_stream_info(desc->s);
155
  if (res < 0) {
156
    fprintf(stderr, "Cannot find codec parameters for %s\n", fname);
157
158
    return NULL;
159
  }
160 025da5a8 Luca Abeni
  desc->streams = 0;
161 1e8dedd8 Luca Abeni
  desc->last_ts = 0;
162
  desc->base_ts = 0;
163 1cc19859 Luca Abeni
  desc->loop = 0;
164
  cfg_tags = config_parse(config);
165
  if (cfg_tags) {
166 37f8b121 Luca Abeni
    const char *media;
167
168 1cc19859 Luca Abeni
    config_value_int(cfg_tags, "loop", &desc->loop);
169 37f8b121 Luca Abeni
    media = config_value_str(cfg_tags, "media");
170
    if (media) {
171
      if (!strcmp(media, "audio")) {
172
        audio_streams = 0;
173
        video_streams = 1;
174
      } else if (!strcmp(media, "video")) {
175
        audio_streams = 1;
176
        video_streams = 0;
177
      } else if (!strcmp(media, "av")) {
178
        audio_streams = 0;
179
        video_streams = 0;
180
      }
181
    }
182 1cc19859 Luca Abeni
  }
183 dcc42706 Luca Abeni
  free(cfg_tags);
184 1e8dedd8 Luca Abeni
  for (i = 0; i < desc->s->nb_streams; i++) {
185 025da5a8 Luca Abeni
    if (desc->s->streams[i]->codec->codec_type == CODEC_TYPE_VIDEO) {
186
      if (video_streams++ == 0) {
187
        desc->streams |= 1ULL << i;
188
      }
189 1e8dedd8 Luca Abeni
      fprintf(stderr, "Video Frame Rate = %d/%d --- Period: %lld\n",
190
              desc->s->streams[i]->r_frame_rate.num,
191
              desc->s->streams[i]->r_frame_rate.den,
192
              av_rescale(1000000, desc->s->streams[i]->r_frame_rate.den, desc->s->streams[i]->r_frame_rate.num));
193
      *period = av_rescale(1000000, desc->s->streams[i]->r_frame_rate.den, desc->s->streams[i]->r_frame_rate.num);
194
    }
195 025da5a8 Luca Abeni
    if (desc->s->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO) {
196
      if (audio_streams++ == 0) {
197
        desc->streams |= 1ULL << i;
198
      }
199 1e8dedd8 Luca Abeni
    }
200 a6497b4b Luca Abeni
    if (desc->s->streams[i]->codec->codec_id == CODEC_ID_MPEG4) {
201
      desc->bsf[i] = av_bitstream_filter_init("dump_extra");
202 2360396a Luca Abeni
    } else if (desc->s->streams[i]->codec->codec_id == CODEC_ID_H264) {
203
      desc->bsf[i] = av_bitstream_filter_init("h264_mp4toannexb");
204 a6497b4b Luca Abeni
    } else {
205
      desc->bsf[i] = NULL;
206
    }
207 1e8dedd8 Luca Abeni
  }
208
209
  dump_format(desc->s, 0, fname, 0);
210
211
  return desc;
212
}
213
214 fcc01ba5 Luca Abeni
static void avf_close(struct chunkiser_ctx *s)
215 1e8dedd8 Luca Abeni
{
216 94563418 Luca Abeni
  int i;
217
218
  for (i = 0; i < s->s->nb_streams; i++) {
219
    if (s->bsf[i]) {
220
      av_bitstream_filter_close(s->bsf[i]);
221
    }
222
  }
223
  av_close_input_file(s->s);
224
  free(s);
225 1e8dedd8 Luca Abeni
}
226
227 fcc01ba5 Luca Abeni
static uint8_t *avf_chunkise(struct chunkiser_ctx *s, int id, int *size, uint64_t *ts)
228 1e8dedd8 Luca Abeni
{
229 851db83d Luca Abeni
  AVPacket pkt;
230
  AVRational new_tb;
231
  int res;
232
  uint8_t *data;
233
  int header_size;
234 1e8dedd8 Luca Abeni
235 851db83d Luca Abeni
  res = av_read_frame(s->s, &pkt);
236
  if (res < 0) {
237
    if (s->loop) {
238
      if (input_stream_rewind(s) >= 0) {
239 a6497b4b Luca Abeni
        *size = 0;
240 851db83d Luca Abeni
        *ts = s->last_ts;
241 a6497b4b Luca Abeni
242
        return NULL;
243
      }
244
    }
245 851db83d Luca Abeni
    fprintf(stderr, "AVPacket read failed: %d!!!\n", res);
246
    *size = -1;
247 1e8dedd8 Luca Abeni
248 851db83d Luca Abeni
    return NULL;
249
  }
250 025da5a8 Luca Abeni
  if ((s->streams & (1ULL << pkt.stream_index)) == 0) {
251 851db83d Luca Abeni
    *size = 0;
252
    *ts = s->last_ts;
253
    av_free_packet(&pkt);
254
255
    return NULL;
256
  }
257
  if (s->bsf[pkt.stream_index]) {
258
    AVPacket new_pkt= pkt;
259
    int res;
260
261
    res = av_bitstream_filter_filter(s->bsf[pkt.stream_index],
262
                                     s->s->streams[pkt.stream_index]->codec,
263
                                     NULL, &new_pkt.data, &new_pkt.size,
264
                                     pkt.data, pkt.size, pkt.flags & AV_PKT_FLAG_KEY);
265
    if(res > 0){
266 1e8dedd8 Luca Abeni
      av_free_packet(&pkt);
267 851db83d Luca Abeni
      new_pkt.destruct= av_destruct_packet;
268
    } else if(res < 0){
269
      fprintf(stderr, "%s failed for stream %d, codec %s: ",
270
                      s->bsf[pkt.stream_index]->filter->name,
271
                      pkt.stream_index,
272
                      s->s->streams[pkt.stream_index]->codec->codec->name);
273
      fprintf(stderr, "%d\n", res);
274
      *size = 0;
275 1e8dedd8 Luca Abeni
276
      return NULL;
277
    }
278 851db83d Luca Abeni
    pkt= new_pkt;
279
  }
280
281
  switch (s->s->streams[pkt.stream_index]->codec->codec_type) {
282
    case CODEC_TYPE_VIDEO:
283
      header_size = VIDEO_PAYLOAD_HEADER_SIZE;
284
      break;
285 52f45fc1 Luca Abeni
    case CODEC_TYPE_AUDIO:
286
      header_size = AUDIO_PAYLOAD_HEADER_SIZE;
287
      break;
288 851db83d Luca Abeni
    default:
289
      /* Cannot arrive here... */
290
      fprintf(stderr, "Internal chunkiser error!\n");
291
      exit(-1);
292
  }
293
  *size = pkt.size + header_size + FRAME_HEADER_SIZE;
294
  data = malloc(*size);
295
  if (data == NULL) {
296
    *size = -1;
297 1e8dedd8 Luca Abeni
    av_free_packet(&pkt);
298
299 851db83d Luca Abeni
    return NULL;
300
  }
301
  switch (s->s->streams[pkt.stream_index]->codec->codec_type) {
302
    case CODEC_TYPE_VIDEO:
303
      video_header_fill(data, s->s->streams[pkt.stream_index]);
304 7e44761d Luca Abeni
      new_tb.den = s->s->streams[pkt.stream_index]->avg_frame_rate.num;
305
      new_tb.num = s->s->streams[pkt.stream_index]->avg_frame_rate.den;
306 851db83d Luca Abeni
      if (new_tb.num == 0) {
307 7e44761d Luca Abeni
        new_tb.den = s->s->streams[pkt.stream_index]->r_frame_rate.num;
308
        new_tb.num = s->s->streams[pkt.stream_index]->r_frame_rate.den;
309 851db83d Luca Abeni
      }
310
      break;
311 52f45fc1 Luca Abeni
    case CODEC_TYPE_AUDIO:
312
      audio_header_fill(data, s->s->streams[pkt.stream_index]);
313
      new_tb = (AVRational){s->s->streams[pkt.stream_index]->codec->frame_size, s->s->streams[pkt.stream_index]->codec->sample_rate};
314
      break;
315 851db83d Luca Abeni
    default:
316
      /* Cannot arrive here... */
317
      fprintf(stderr, "Internal chunkiser error!\n");
318
      exit(-1);
319
  }
320
  data[header_size - 1] = 1;
321
  frame_header_fill(data + header_size, *size - header_size - FRAME_HEADER_SIZE, &pkt, s->s->streams[pkt.stream_index], new_tb, s->base_ts);
322
323
  memcpy(data + header_size + FRAME_HEADER_SIZE, pkt.data, pkt.size);
324
  *ts = av_rescale_q(pkt.dts, s->s->streams[pkt.stream_index]->time_base, AV_TIME_BASE_Q);
325
  //dprintf("pkt.dts=%ld TS1=%lu" , pkt.dts, *ts);
326
  *ts += s->base_ts;
327
  //dprintf(" TS2=%lu\n",*ts);
328
  s->last_ts = *ts;
329
  av_free_packet(&pkt);
330
331
  return data;
332 1e8dedd8 Luca Abeni
}
333
334
#if 0
335
int chunk_read_avs1(void *s_h, struct chunk *c)
336
{
337
    AVFormatContext *s = s_h;
338
    static AVPacket pkt;
339
    static int inited;
340
    AVStream *st;
341
    int res;
342
    int cnt;
343
    static uint8_t static_buff[STATIC_BUFF_SIZE];
344
    uint8_t *p, *pcurr;
345
    static uint8_t *p1;
346
    static struct chunk c2;
347
    int f1;
348
    static int f2;
349

350
    if (p1) {
351
        c2.id = c->id;
352
        *c = c2;
353
        p1 = NULL;
354

355
        return f2;
356
    }
357

358
    p = static_buff;
359
    p1 = static_buff + STATIC_BUFF_SIZE / 2;
360
    if (inited == 0) {
361
        inited = 1;
362
        res = av_read_frame(s, &pkt);
363
        if (res < 0) {
364
            fprintf(stderr, "First read failed: %d!!!\n", res);
365

366
            return 0;
367
        }
368
        if ((pkt.flags & PKT_FLAG_KEY) == 0) {
369
            fprintf(stderr, "First frame is not key frame!!!\n");
370

371
            return 0;
372
        }
373
    }
374
    cnt = 0; f1 = 0; f2 = 0;
375
    c->stride_size = 2;
376
    c2.stride_size = 2;
377
    pcurr = p1;
378
    if (pkt.size > 0) {
379
        memcpy(p, pkt.data, pkt.size);
380
        c->frame[0] = p;
381
        c->frame_len[0] = pkt.size;
382
        f1++;
383
        p += pkt.size;
384
    }
385
    while (1) {
386
        res = av_read_frame(s, &pkt);
387
        if (res >= 0) {
388
            st = s->streams[pkt.stream_index];
389
            if (pkt.flags & PKT_FLAG_KEY) {
390
                cnt++;
391
                if (cnt == 2) {
392
                    return f1;
393
                }
394
            }
395
            memcpy(pcurr, pkt.data, pkt.size);
396
            if (pcurr == p) {
397
                c->frame[f1] = pcurr;
398
                c->frame_len[f1] = pkt.size;
399
                p += pkt.size;
400
                pcurr = p1;
401
                f1++;
402
            } else {
403
                c2.frame[f2] = pcurr;
404
                c2.frame_len[f2] = pkt.size;
405
                p1 += pkt.size;
406
                pcurr = p;
407
                f2++;
408
            }
409
        } else {
410
            pkt.size = 0;
411

412
            return f1;
413
        }
414
    }
415

416
    return 0;
417
}
418
#endif
419 c0c735aa Luca Abeni
420
struct chunkiser_iface in_avf = {
421
  .open = avf_open,
422
  .close = avf_close,
423
  .chunkise = avf_chunkise,
424
};