Statistics
| Branch: | Revision:

streamers / Chunkiser / input-stream-avs.c @ 52976315

History | View | Annotate | Download (7.28 KB)

1
/*
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

    
9
#include "../input-stream.h"
10
#define STATIC_BUFF_SIZE 1000 * 1024
11
#define HEADER_REFRESH_PERIOD 50
12

    
13
struct input_stream {
14
  AVFormatContext *s;
15
  int audio_stream;
16
  int video_stream;
17
  int64_t last_ts;
18
  int64_t base_ts;
19
  int frames_since_global_headers;
20
};
21

    
22
struct input_stream *input_stream_open(const char *fname, int *period)
23
{
24
  struct input_stream *desc;
25
  int i, res;
26

    
27
  avcodec_register_all();
28
  av_register_all();
29

    
30
  desc = malloc(sizeof(struct input_stream));
31
  if (desc == NULL) {
32
    return NULL;
33
  }
34
  res = av_open_input_file(&desc->s, fname, NULL, 0, NULL);
35
  if (res < 0) {
36
    fprintf(stderr, "Error opening %s: %d\n", fname, res);
37

    
38
    return NULL;
39
  }
40

    
41
  res = av_find_stream_info(desc->s);
42
  if (res < 0) {
43
    fprintf(stderr, "Cannot find codec parameters for %s\n", fname);
44

    
45
    return NULL;
46
  }
47
  desc->video_stream = -1;
48
  desc->audio_stream = -1;
49
  desc->last_ts = 0;
50
  desc->base_ts = 0;
51
  desc->frames_since_global_headers = 0;
52
  for (i = 0; i < desc->s->nb_streams; i++) {
53
    if (desc->video_stream == -1 && desc->s->streams[i]->codec->codec_type == CODEC_TYPE_VIDEO) {
54
      desc->video_stream = i;
55
      fprintf(stderr, "Video Frame Rate = %d/%d --- Period: %lld\n",
56
              desc->s->streams[i]->r_frame_rate.num,
57
              desc->s->streams[i]->r_frame_rate.den,
58
              av_rescale(1000000, desc->s->streams[i]->r_frame_rate.den, desc->s->streams[i]->r_frame_rate.num));
59
      *period = av_rescale(1000000, desc->s->streams[i]->r_frame_rate.den, desc->s->streams[i]->r_frame_rate.num);
60
    }
61
    if (desc->audio_stream == -1 && desc->s->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO) {
62
      desc->audio_stream = i;
63
    }
64
  }
65

    
66
  dump_format(desc->s, 0, fname, 0);
67

    
68
  return desc;
69
}
70

    
71
void input_stream_close(struct input_stream *s)
72
{
73
    av_close_input_file(s->s);
74
    free(s);
75
}
76

    
77
int input_stream_rewind(struct input_stream *s)
78
{
79
    int ret;
80

    
81
    ret = av_seek_frame(s->s,-1,0,0);
82
    s->base_ts = s->last_ts;
83

    
84
    return ret;
85
}
86

    
87

    
88
#if 0
89
int input_get_1(struct input_stream *s, struct chunk *c)
90
{
91
    static AVPacket pkt;
92
    static int inited;
93
    AVStream *st;
94
    int res;
95
    static uint8_t static_buff[STATIC_BUFF_SIZE];
96
    static int cid;
97
    uint8_t *p;
98

99
    p = static_buff;
100
    if (inited == 0) {
101
        inited = 1;
102
        res = av_read_frame(s->s, &pkt);
103
        if (res < 0) {
104
            fprintf(stderr, "First read failed: %d!!!\n", res);
105

106
            return 0;
107
        }
108
        if ((pkt.flags & PKT_FLAG_KEY) == 0) {
109
            fprintf(stderr, "First frame is not key frame!!!\n");
110

111
            return 0;
112
        }
113
    }
114
    c->timestamp = pkt.dts;
115
    memcpy(p, pkt.data, pkt.size);
116
    p += pkt.size;
117
    while (1) {
118
        res = av_read_frame(s->s, &pkt);
119
        if (res >= 0) {
120
            st = s->s->streams[pkt.stream_index];
121
            if (pkt.flags & PKT_FLAG_KEY) {
122
                c->size = p - static_buff;
123
                c->data = malloc(c->size);
124
                if (c->data == NULL) {
125
                  return 0;
126
                }
127
                memcpy(c->data, static_buff, c->size);
128
                c->attributes_size = 0;
129
                c->attributes = NULL;
130
                c->id = cid++; 
131
                return 1;
132
            }
133
            memcpy(p, pkt.data, pkt.size);
134
            p += pkt.size;
135
        } else {
136
            if (p - static_buff > 0) {
137
                c->size = p - static_buff;
138
                c->data = malloc(c->size);
139
                if (c->data == NULL) {
140
                  return 0;
141
                }
142
                memcpy(c->data, static_buff, c->size);
143
                c->attributes_size = 0;
144
                c->attributes = NULL;
145
                c->id = cid++; 
146
                return 1;
147
            }
148
            return 0;
149
        }
150
    }
151

152
    return 0;
153
}
154
#endif
155

    
156
uint8_t *chunkise(struct input_stream *s, int id, int *size, uint64_t *ts)
157
{
158
    AVPacket pkt;
159
    int res;
160
    uint8_t *data;
161
    int header_out;
162

    
163
    res = av_read_frame(s->s, &pkt);
164
    if (res < 0) {
165
      if (input_stream_rewind(s) < 0) {
166
        fprintf(stderr, "AVPacket read failed: %d!!!\n", res);
167
        *size = -1;
168

    
169
        return NULL;
170
      }
171
      *size = 0;
172
      *ts = s->last_ts;
173

    
174
      return NULL;
175
    }
176
    if (pkt.stream_index != s->video_stream) {
177
      *size = 0;
178
      *ts = s->last_ts;
179
      av_free_packet(&pkt);
180

    
181
      return NULL;
182
    }
183
    header_out = (pkt.flags & PKT_FLAG_KEY) != 0;
184
    if (header_out == 0) {
185
      s->frames_since_global_headers++;
186
      if (s->frames_since_global_headers == HEADER_REFRESH_PERIOD) {
187
        s->frames_since_global_headers = 0;
188
        header_out = 1;
189
      }
190
    }
191
    *size = pkt.size + s->s->streams[pkt.stream_index]->codec->extradata_size * header_out;
192
    data = malloc(*size);
193
    if (data == NULL) {
194
      *size = -1;
195
      av_free_packet(&pkt);
196

    
197
      return NULL;
198
    }
199
    if (header_out && s->s->streams[pkt.stream_index]->codec->extradata_size) {
200
      memcpy(data, s->s->streams[pkt.stream_index]->codec->extradata, s->s->streams[pkt.stream_index]->codec->extradata_size);
201
      memcpy(data + s->s->streams[pkt.stream_index]->codec->extradata_size, pkt.data, pkt.size);
202
    } else {
203
      memcpy(data, pkt.data, pkt.size);
204
    }
205
    *ts = av_rescale_q(pkt.dts, s->s->streams[pkt.stream_index]->time_base, AV_TIME_BASE_Q);
206
    *ts += s->base_ts;
207
    s->last_ts = *ts;
208
    av_free_packet(&pkt);
209

    
210
    return data;
211
}
212

    
213
#if 0
214
int chunk_read_avs1(void *s_h, struct chunk *c)
215
{
216
    AVFormatContext *s = s_h;
217
    static AVPacket pkt;
218
    static int inited;
219
    AVStream *st;
220
    int res;
221
    int cnt;
222
    static uint8_t static_buff[STATIC_BUFF_SIZE];
223
    uint8_t *p, *pcurr;
224
    static uint8_t *p1;
225
    static struct chunk c2;
226
    int f1;
227
    static int f2;
228

229
    if (p1) {
230
        c2.id = c->id;
231
        *c = c2;
232
        p1 = NULL;
233

234
        return f2;
235
    }
236

237
    p = static_buff;
238
    p1 = static_buff + STATIC_BUFF_SIZE / 2;
239
    if (inited == 0) {
240
        inited = 1;
241
        res = av_read_frame(s, &pkt);
242
        if (res < 0) {
243
            fprintf(stderr, "First read failed: %d!!!\n", res);
244

245
            return 0;
246
        }
247
        if ((pkt.flags & PKT_FLAG_KEY) == 0) {
248
            fprintf(stderr, "First frame is not key frame!!!\n");
249

250
            return 0;
251
        }
252
    }
253
    cnt = 0; f1 = 0; f2 = 0;
254
    c->stride_size = 2;
255
    c2.stride_size = 2;
256
    pcurr = p1;
257
    if (pkt.size > 0) {
258
        memcpy(p, pkt.data, pkt.size);
259
        c->frame[0] = p;
260
        c->frame_len[0] = pkt.size;
261
        f1++;
262
        p += pkt.size;
263
    }
264
    while (1) {
265
        res = av_read_frame(s, &pkt);
266
        if (res >= 0) {
267
            st = s->streams[pkt.stream_index];
268
            if (pkt.flags & PKT_FLAG_KEY) {
269
                cnt++;
270
                if (cnt == 2) {
271
                    return f1;
272
                }
273
            }
274
            memcpy(pcurr, pkt.data, pkt.size);
275
            if (pcurr == p) {
276
                c->frame[f1] = pcurr;
277
                c->frame_len[f1] = pkt.size;
278
                p += pkt.size;
279
                pcurr = p1;
280
                f1++;
281
            } else {
282
                c2.frame[f2] = pcurr;
283
                c2.frame_len[f2] = pkt.size;
284
                p1 += pkt.size;
285
                pcurr = p;
286
                f2++;
287
            }
288
        } else {
289
            pkt.size = 0;
290

291
            return f1;
292
        }
293
    }
294

295
    return 0;
296
}
297
#endif