~ubuntu-branches/ubuntu/intrepid/gstreamer0.10-ffmpeg/intrepid

« back to all changes in this revision

Viewing changes to gst-libs/ext/ffmpeg/libavformat/yuv4mpeg.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastian Dröge
  • Date: 2006-04-01 16:13:43 UTC
  • mto: (1.2.2 lenny)
  • mto: This revision was merged to the branch mainline in revision 5.
  • Revision ID: james.westby@ubuntu.com-20060401161343-n621cgjlujio0otg
Tags: upstream-0.10.1
Import upstream version 0.10.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
 *
15
15
 * You should have received a copy of the GNU Lesser General Public
16
16
 * License along with this library; if not, write to the Free Software
17
 
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
17
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
18
 */
19
19
#include "avformat.h"
20
20
 
22
22
#define Y4M_FRAME_MAGIC "FRAME"
23
23
#define Y4M_LINE_MAX 256
24
24
 
 
25
struct frame_attributes {
 
26
    int interlaced_frame;
 
27
    int top_field_first;
 
28
};
 
29
 
25
30
#ifdef CONFIG_MUXERS
26
31
 
27
32
static int yuv4_generate_header(AVFormatContext *s, char* buf)
37
42
    height = st->codec->height;
38
43
 
39
44
    av_reduce(&raten, &rated, st->codec->time_base.den, st->codec->time_base.num, (1UL<<31)-1);
40
 
    
 
45
 
41
46
    aspectn = st->codec->sample_aspect_ratio.num;
42
47
    aspectd = st->codec->sample_aspect_ratio.den;
43
 
    
 
48
 
44
49
    if ( aspectn == 0 && aspectd == 1 ) aspectd = 0;  // 0:0 means unknown
45
50
 
46
51
    inter = 'p'; /* progressive is the default */
75
80
                 inter,
76
81
                 aspectn, aspectd,
77
82
                 colorspace);
78
 
                 
 
83
 
79
84
    return n;
80
85
}
81
86
 
96
101
    /* for the first packet we have to output the header as well */
97
102
    if (*first_pkt) {
98
103
        *first_pkt = 0;
99
 
        if (yuv4_generate_header(s, buf2) < 0) {
100
 
            av_log(s, AV_LOG_ERROR, "Error. YUV4MPEG stream header write failed.\n");
101
 
            return AVERROR_IO;
102
 
        } else {
103
 
            put_buffer(pb, buf2, strlen(buf2)); 
104
 
        }
 
104
        if (yuv4_generate_header(s, buf2) < 0) {
 
105
            av_log(s, AV_LOG_ERROR, "Error. YUV4MPEG stream header write failed.\n");
 
106
            return AVERROR_IO;
 
107
        } else {
 
108
            put_buffer(pb, buf2, strlen(buf2));
 
109
        }
105
110
    }
106
111
 
107
112
    /* construct frame header */
108
 
    
 
113
 
109
114
    m = snprintf(buf1, sizeof(buf1), "%s\n", Y4M_FRAME_MAGIC);
110
115
    put_buffer(pb, buf1, strlen(buf1));
111
116
 
112
117
    width = st->codec->width;
113
118
    height = st->codec->height;
114
 
    
 
119
 
115
120
    ptr = picture->data[0];
116
121
    for(i=0;i<height;i++) {
117
122
        put_buffer(pb, ptr, width);
126
131
 
127
132
    ptr1 = picture->data[1];
128
133
    ptr2 = picture->data[2];
129
 
    for(i=0;i<height;i++) {             /* Cb */
 
134
    for(i=0;i<height;i++) {     /* Cb */
130
135
        put_buffer(pb, ptr1, width);
131
136
        ptr1 += picture->linesize[1];
132
137
    }
133
 
    for(i=0;i<height;i++) {     /* Cr */
 
138
    for(i=0;i<height;i++) {     /* Cr */
134
139
        put_buffer(pb, ptr2, width);
135
140
            ptr2 += picture->linesize[2];
136
141
    }
142
147
static int yuv4_write_header(AVFormatContext *s)
143
148
{
144
149
    int* first_pkt = s->priv_data;
145
 
    
 
150
 
146
151
    if (s->nb_streams != 1)
147
152
        return AVERROR_IO;
148
 
    
 
153
 
149
154
    if (s->streams[0]->codec->pix_fmt == PIX_FMT_YUV411P) {
150
155
        av_log(s, AV_LOG_ERROR, "Warning: generating rarely used 4:1:1 YUV stream, some mjpegtools might not work.\n");
151
 
    } 
152
 
    else if ((s->streams[0]->codec->pix_fmt != PIX_FMT_YUV420P) && 
153
 
             (s->streams[0]->codec->pix_fmt != PIX_FMT_YUV422P) && 
154
 
             (s->streams[0]->codec->pix_fmt != PIX_FMT_GRAY8) && 
 
156
    }
 
157
    else if ((s->streams[0]->codec->pix_fmt != PIX_FMT_YUV420P) &&
 
158
             (s->streams[0]->codec->pix_fmt != PIX_FMT_YUV422P) &&
 
159
             (s->streams[0]->codec->pix_fmt != PIX_FMT_GRAY8) &&
155
160
             (s->streams[0]->codec->pix_fmt != PIX_FMT_YUV444P)) {
156
161
        av_log(s, AV_LOG_ERROR, "ERROR: yuv4mpeg only handles yuv444p, yuv422p, yuv420p, yuv411p and gray pixel formats. Use -pix_fmt to select one.\n");
157
 
        return AVERROR_IO;
 
162
        return AVERROR_IO;
158
163
    }
159
 
    
 
164
 
160
165
    *first_pkt = 1;
161
166
    return 0;
162
167
}
191
196
    char *tokstart,*tokend,*header_end;
192
197
    int i;
193
198
    ByteIOContext *pb = &s->pb;
194
 
    int width=-1, height=-1, raten=0, rated=0, aspectn=0, aspectd=0,interlaced_frame=0,top_field_first=0;
 
199
    int width=-1, height=-1, raten=0, rated=0, aspectn=0, aspectd=0;
195
200
    enum PixelFormat pix_fmt=PIX_FMT_NONE,alt_pix_fmt=PIX_FMT_NONE;
196
201
    AVStream *st;
197
 
    
 
202
    struct frame_attributes *s1 = s->priv_data;
 
203
 
198
204
    for (i=0; i<MAX_YUV4_HEADER; i++) {
199
205
        header[i] = get_byte(pb);
200
 
        if (header[i] == '\n') {
201
 
            header[i+1] = 0x20;  // Add a space after last option. Makes parsing "444" vs "444alpha" easier.
202
 
            header[i+2] = 0;
203
 
            break;
204
 
        }
 
206
        if (header[i] == '\n') {
 
207
            header[i+1] = 0x20;  // Add a space after last option. Makes parsing "444" vs "444alpha" easier.
 
208
            header[i+2] = 0;
 
209
            break;
 
210
        }
205
211
    }
206
212
    if (i == MAX_YUV4_HEADER) return -1;
207
213
    if (strncmp(header, Y4M_MAGIC, strlen(Y4M_MAGIC))) return -1;
208
214
 
 
215
    s1->interlaced_frame = 0;
 
216
    s1->top_field_first = 0;
209
217
    header_end = &header[i+1]; // Include space
210
218
    for(tokstart = &header[strlen(Y4M_MAGIC) + 1]; tokstart < header_end; tokstart++) {
211
219
        if (*tokstart==0x20) continue;
247
255
            case '?':
248
256
                break;
249
257
            case 'p':
250
 
                interlaced_frame=0;
 
258
                s1->interlaced_frame=0;
251
259
                break;
252
260
            case 't':
253
 
                interlaced_frame=1;
254
 
                top_field_first=1;
 
261
                s1->interlaced_frame=1;
 
262
                s1->top_field_first=1;
255
263
                break;
256
264
            case 'b':
257
 
                interlaced_frame=1;
258
 
                top_field_first=0;
 
265
                s1->interlaced_frame=1;
 
266
                s1->top_field_first=0;
259
267
                break;
260
268
            case 'm':
261
269
                av_log(s, AV_LOG_ERROR, "YUV4MPEG stream contains mixed interlaced and non-interlaced frames.\n");
293
301
            while(tokstart<header_end&&*tokstart!=0x20) tokstart++;
294
302
            break;
295
303
        }
296
 
    }            
 
304
    }
297
305
 
298
306
    if ((width == -1) || (height == -1)) {
299
307
        av_log(s, AV_LOG_ERROR, "YUV4MPEG has invalid header.\n");
300
 
        return -1;        
 
308
        return -1;
301
309
    }
302
 
    
 
310
 
303
311
    if (pix_fmt == PIX_FMT_NONE) {
304
312
        if (alt_pix_fmt == PIX_FMT_NONE)
305
313
            pix_fmt = PIX_FMT_YUV420P;
317
325
        // Pixel aspect unknown
318
326
        aspectd = 1;
319
327
    }
320
 
        
 
328
 
321
329
    st = av_new_stream(s, 0);
322
330
    st = s->streams[0];
323
331
    st->codec->width = width;
338
346
    char header[MAX_FRAME_HEADER+1];
339
347
    int packet_size, width, height;
340
348
    AVStream *st = s->streams[0];
 
349
    struct frame_attributes *s1 = s->priv_data;
341
350
 
342
351
    for (i=0; i<MAX_FRAME_HEADER; i++) {
343
352
        header[i] = get_byte(&s->pb);
344
 
        if (header[i] == '\n') {
345
 
            header[i+1] = 0;
346
 
            break;
347
 
        }
 
353
        if (header[i] == '\n') {
 
354
            header[i+1] = 0;
 
355
            break;
 
356
        }
348
357
    }
349
358
    if (i == MAX_FRAME_HEADER) return -1;
350
359
    if (strncmp(header, Y4M_FRAME_MAGIC, strlen(Y4M_FRAME_MAGIC))) return -1;
351
 
    
 
360
 
352
361
    width = st->codec->width;
353
362
    height = st->codec->height;
354
363
 
359
368
    if (av_get_packet(&s->pb, pkt, packet_size) != packet_size)
360
369
        return AVERROR_IO;
361
370
 
 
371
    if (s->streams[0]->codec->coded_frame) {
 
372
        s->streams[0]->codec->coded_frame->interlaced_frame = s1->interlaced_frame;
 
373
        s->streams[0]->codec->coded_frame->top_field_first = s1->top_field_first;
 
374
    }
 
375
 
362
376
    pkt->stream_index = 0;
363
377
    return 0;
364
378
}
382
396
AVInputFormat yuv4mpegpipe_iformat = {
383
397
    "yuv4mpegpipe",
384
398
    "YUV4MPEG pipe format",
385
 
    0,
 
399
    sizeof(struct frame_attributes),
386
400
    yuv4_probe,
387
401
    yuv4_read_header,
388
402
    yuv4_read_packet,