Statistics
| Branch: | Revision:

streamers / Chunkiser / input-stream-avs.c @ 9c45209f

History | View | Annotate | Download (6.96 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
  int frames_since_global_headers;
19
};
20

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

    
26
  avcodec_register_all();
27
  av_register_all();
28

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

    
37
    return NULL;
38
  }
39

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

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

    
64
  dump_format(desc->s, 0, fname, 0);
65

    
66
  return desc;
67
}
68

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

    
75
#if 0
76
int input_get_1(struct input_stream *s, struct chunk *c)
77
{
78
    static AVPacket pkt;
79
    static int inited;
80
    AVStream *st;
81
    int res;
82
    static uint8_t static_buff[STATIC_BUFF_SIZE];
83
    static int cid;
84
    uint8_t *p;
85

86
    p = static_buff;
87
    if (inited == 0) {
88
        inited = 1;
89
        res = av_read_frame(s->s, &pkt);
90
        if (res < 0) {
91
            fprintf(stderr, "First read failed: %d!!!\n", res);
92

93
            return 0;
94
        }
95
        if ((pkt.flags & PKT_FLAG_KEY) == 0) {
96
            fprintf(stderr, "First frame is not key frame!!!\n");
97

98
            return 0;
99
        }
100
    }
101
    c->timestamp = pkt.dts;
102
    memcpy(p, pkt.data, pkt.size);
103
    p += pkt.size;
104
    while (1) {
105
        res = av_read_frame(s->s, &pkt);
106
        if (res >= 0) {
107
            st = s->s->streams[pkt.stream_index];
108
            if (pkt.flags & PKT_FLAG_KEY) {
109
                c->size = p - static_buff;
110
                c->data = malloc(c->size);
111
                if (c->data == NULL) {
112
                  return 0;
113
                }
114
                memcpy(c->data, static_buff, c->size);
115
                c->attributes_size = 0;
116
                c->attributes = NULL;
117
                c->id = cid++; 
118
                return 1;
119
            }
120
            memcpy(p, pkt.data, pkt.size);
121
            p += pkt.size;
122
        } else {
123
            if (p - static_buff > 0) {
124
                c->size = p - static_buff;
125
                c->data = malloc(c->size);
126
                if (c->data == NULL) {
127
                  return 0;
128
                }
129
                memcpy(c->data, static_buff, c->size);
130
                c->attributes_size = 0;
131
                c->attributes = NULL;
132
                c->id = cid++; 
133
                return 1;
134
            }
135
            return 0;
136
        }
137
    }
138

139
    return 0;
140
}
141
#endif
142

    
143
uint8_t *chunkise(struct input_stream *s, int id, int *size, uint64_t *ts)
144
{
145
    AVPacket pkt;
146
    int res;
147
    uint8_t *data;
148
    int header_out;
149

    
150
    res = av_read_frame(s->s, &pkt);
151
    if (res < 0) {
152
      fprintf(stderr, "AVPacket read failed: %d!!!\n", res);
153
      *size = -1;
154

    
155
      return NULL;
156
    }
157
    if (pkt.stream_index != s->video_stream) {
158
      *size = 0;
159
      *ts = s->last_ts;
160
      av_free_packet(&pkt);
161

    
162
      return NULL;
163
    }
164
    header_out = (pkt.flags & PKT_FLAG_KEY) != 0;
165
    if (header_out == 0) {
166
      s->frames_since_global_headers++;
167
      if (s->frames_since_global_headers == HEADER_REFRESH_PERIOD) {
168
        s->frames_since_global_headers = 0;
169
        header_out = 1;
170
      }
171
    }
172
    *size = pkt.size + s->s->streams[pkt.stream_index]->codec->extradata_size * header_out;
173
    data = malloc(*size);
174
    if (data == NULL) {
175
      *size = -1;
176
      av_free_packet(&pkt);
177

    
178
      return NULL;
179
    }
180
    if (header_out && s->s->streams[pkt.stream_index]->codec->extradata_size) {
181
      memcpy(data, s->s->streams[pkt.stream_index]->codec->extradata, s->s->streams[pkt.stream_index]->codec->extradata_size);
182
      memcpy(data + s->s->streams[pkt.stream_index]->codec->extradata_size, pkt.data, pkt.size);
183
    } else {
184
      memcpy(data, pkt.data, pkt.size);
185
    }
186
    *ts = av_rescale_q(pkt.dts, s->s->streams[pkt.stream_index]->time_base, AV_TIME_BASE_Q);
187
    s->last_ts = *ts;
188
    av_free_packet(&pkt);
189

    
190
    return data;
191
}
192

    
193
#if 0
194
int chunk_read_avs1(void *s_h, struct chunk *c)
195
{
196
    AVFormatContext *s = s_h;
197
    static AVPacket pkt;
198
    static int inited;
199
    AVStream *st;
200
    int res;
201
    int cnt;
202
    static uint8_t static_buff[STATIC_BUFF_SIZE];
203
    uint8_t *p, *pcurr;
204
    static uint8_t *p1;
205
    static struct chunk c2;
206
    int f1;
207
    static int f2;
208

209
    if (p1) {
210
        c2.id = c->id;
211
        *c = c2;
212
        p1 = NULL;
213

214
        return f2;
215
    }
216

217
    p = static_buff;
218
    p1 = static_buff + STATIC_BUFF_SIZE / 2;
219
    if (inited == 0) {
220
        inited = 1;
221
        res = av_read_frame(s, &pkt);
222
        if (res < 0) {
223
            fprintf(stderr, "First read failed: %d!!!\n", res);
224

225
            return 0;
226
        }
227
        if ((pkt.flags & PKT_FLAG_KEY) == 0) {
228
            fprintf(stderr, "First frame is not key frame!!!\n");
229

230
            return 0;
231
        }
232
    }
233
    cnt = 0; f1 = 0; f2 = 0;
234
    c->stride_size = 2;
235
    c2.stride_size = 2;
236
    pcurr = p1;
237
    if (pkt.size > 0) {
238
        memcpy(p, pkt.data, pkt.size);
239
        c->frame[0] = p;
240
        c->frame_len[0] = pkt.size;
241
        f1++;
242
        p += pkt.size;
243
    }
244
    while (1) {
245
        res = av_read_frame(s, &pkt);
246
        if (res >= 0) {
247
            st = s->streams[pkt.stream_index];
248
            if (pkt.flags & PKT_FLAG_KEY) {
249
                cnt++;
250
                if (cnt == 2) {
251
                    return f1;
252
                }
253
            }
254
            memcpy(pcurr, pkt.data, pkt.size);
255
            if (pcurr == p) {
256
                c->frame[f1] = pcurr;
257
                c->frame_len[f1] = pkt.size;
258
                p += pkt.size;
259
                pcurr = p1;
260
                f1++;
261
            } else {
262
                c2.frame[f2] = pcurr;
263
                c2.frame_len[f2] = pkt.size;
264
                p1 += pkt.size;
265
                pcurr = p;
266
                f2++;
267
            }
268
        } else {
269
            pkt.size = 0;
270

271
            return f1;
272
        }
273
    }
274

275
    return 0;
276
}
277
#endif