Statistics
| Branch: | Revision:

streamers / Chunkiser / input-stream-avs.c @ 0aaea2fb

History | View | Annotate | Download (6.03 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 <chunk.h>
10

    
11
#include "../input.h"
12
#define STATIC_BUFF_SIZE 1000 * 1024
13

    
14
struct input_stream {
15
  AVFormatContext *s;
16
  int audio_stream;
17
  int video_stream;
18
};
19

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

    
25
  avcodec_register_all();
26
  av_register_all();
27

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

    
36
    return NULL;
37
  }
38

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

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

    
61
  dump_format(desc->s, 0, fname, 0);
62

    
63
  return desc;
64
}
65

    
66
void input_stream_close(struct input_stream *s)
67
{
68
    av_close_input_file(s->s);
69
    free(s);
70
}
71

    
72
int input_get_1(struct input_stream *s, struct chunk *c)
73
{
74
    static AVPacket pkt;
75
    static int inited;
76
    AVStream *st;
77
    int res;
78
    static uint8_t static_buff[STATIC_BUFF_SIZE];
79
    static int cid;
80
    uint8_t *p;
81

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

    
89
            return 0;
90
        }
91
        if ((pkt.flags & PKT_FLAG_KEY) == 0) {
92
            fprintf(stderr, "First frame is not key frame!!!\n");
93

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

    
135
    return 0;
136
}
137

    
138
uint8_t *chunkise(struct input_stream *s, int id, int *size, uint64_t *ts)
139
{
140
    AVPacket pkt;
141
    int res;
142
    uint8_t *data;
143

    
144
    res = av_read_frame(s->s, &pkt);
145
    if (res < 0) {
146
      fprintf(stderr, "AVPacket read failed: %d!!!\n", res);
147
      *size = -1;
148

    
149
      return NULL;
150
    }
151
    if (pkt.stream_index != s->video_stream) {
152
      *size = 0;
153

    
154
      return NULL;
155
    }
156

    
157
    *size = pkt.size;
158
    data = malloc(pkt.size);
159
    if (data == NULL) {
160
      *size = -1;
161

    
162
      return NULL;
163
    }
164
    memcpy(data, pkt.data, *size);
165
    *ts = av_rescale_q(pkt.dts, s->s->streams[pkt.stream_index]->time_base, AV_TIME_BASE_Q);
166

    
167
    return data;
168
}
169

    
170
#if 0
171
int chunk_read_avs1(void *s_h, struct chunk *c)
172
{
173
    AVFormatContext *s = s_h;
174
    static AVPacket pkt;
175
    static int inited;
176
    AVStream *st;
177
    int res;
178
    int cnt;
179
    static uint8_t static_buff[STATIC_BUFF_SIZE];
180
    uint8_t *p, *pcurr;
181
    static uint8_t *p1;
182
    static struct chunk c2;
183
    int f1;
184
    static int f2;
185

186
    if (p1) {
187
        c2.id = c->id;
188
        *c = c2;
189
        p1 = NULL;
190

191
        return f2;
192
    }
193

194
    p = static_buff;
195
    p1 = static_buff + STATIC_BUFF_SIZE / 2;
196
    if (inited == 0) {
197
        inited = 1;
198
        res = av_read_frame(s, &pkt);
199
        if (res < 0) {
200
            fprintf(stderr, "First read failed: %d!!!\n", res);
201

202
            return 0;
203
        }
204
        if ((pkt.flags & PKT_FLAG_KEY) == 0) {
205
            fprintf(stderr, "First frame is not key frame!!!\n");
206

207
            return 0;
208
        }
209
    }
210
    cnt = 0; f1 = 0; f2 = 0;
211
    c->stride_size = 2;
212
    c2.stride_size = 2;
213
    pcurr = p1;
214
    if (pkt.size > 0) {
215
        memcpy(p, pkt.data, pkt.size);
216
        c->frame[0] = p;
217
        c->frame_len[0] = pkt.size;
218
        f1++;
219
        p += pkt.size;
220
    }
221
    while (1) {
222
        res = av_read_frame(s, &pkt);
223
        if (res >= 0) {
224
            st = s->streams[pkt.stream_index];
225
            if (pkt.flags & PKT_FLAG_KEY) {
226
                cnt++;
227
                if (cnt == 2) {
228
                    return f1;
229
                }
230
            }
231
            memcpy(pcurr, pkt.data, pkt.size);
232
            if (pcurr == p) {
233
                c->frame[f1] = pcurr;
234
                c->frame_len[f1] = pkt.size;
235
                p += pkt.size;
236
                pcurr = p1;
237
                f1++;
238
            } else {
239
                c2.frame[f2] = pcurr;
240
                c2.frame_len[f2] = pkt.size;
241
                p1 += pkt.size;
242
                pcurr = p;
243
                f2++;
244
            }
245
        } else {
246
            pkt.size = 0;
247

248
            return f1;
249
        }
250
    }
251

252
    return 0;
253
}
254
#endif