~ubuntu-branches/ubuntu/utopic/libav/utopic

« back to all changes in this revision

Viewing changes to libavcodec/vc1_parser.c

  • Committer: Bazaar Package Importer
  • Author(s): Reinhard Tartler
  • Date: 2011-03-20 12:09:31 UTC
  • Revision ID: james.westby@ubuntu.com-20110320120931-nfhi9tiok27gxhw1
Tags: upstream-0.6.2
ImportĀ upstreamĀ versionĀ 0.6.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * VC-1 and WMV3 parser
 
3
 * Copyright (c) 2006-2007 Konstantin Shishkov
 
4
 * Partly based on vc9.c (c) 2005 Anonymous, Alex Beregszaszi, Michael Niedermayer
 
5
 *
 
6
 * This file is part of FFmpeg.
 
7
 *
 
8
 * FFmpeg is free software; you can redistribute it and/or
 
9
 * modify it under the terms of the GNU Lesser General Public
 
10
 * License as published by the Free Software Foundation; either
 
11
 * version 2.1 of the License, or (at your option) any later version.
 
12
 *
 
13
 * FFmpeg is distributed in the hope that it will be useful,
 
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
16
 * Lesser General Public License for more details.
 
17
 *
 
18
 * You should have received a copy of the GNU Lesser General Public
 
19
 * License along with FFmpeg; if not, write to the Free Software
 
20
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
21
 */
 
22
 
 
23
/**
 
24
 * @file
 
25
 * VC-1 and WMV3 parser
 
26
 */
 
27
 
 
28
#include "parser.h"
 
29
#include "vc1.h"
 
30
#include "get_bits.h"
 
31
 
 
32
typedef struct {
 
33
    ParseContext pc;
 
34
    VC1Context v;
 
35
} VC1ParseContext;
 
36
 
 
37
static void vc1_extract_headers(AVCodecParserContext *s, AVCodecContext *avctx,
 
38
                                const uint8_t *buf, int buf_size)
 
39
{
 
40
    VC1ParseContext *vpc = s->priv_data;
 
41
    GetBitContext gb;
 
42
    const uint8_t *start, *end, *next;
 
43
    uint8_t *buf2 = av_mallocz(buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
 
44
 
 
45
    vpc->v.s.avctx = avctx;
 
46
    vpc->v.parse_only = 1;
 
47
    next = buf;
 
48
 
 
49
    for(start = buf, end = buf + buf_size; next < end; start = next){
 
50
        int buf2_size, size;
 
51
 
 
52
        next = find_next_marker(start + 4, end);
 
53
        size = next - start - 4;
 
54
        buf2_size = vc1_unescape_buffer(start + 4, size, buf2);
 
55
        init_get_bits(&gb, buf2, buf2_size * 8);
 
56
        if(size <= 0) continue;
 
57
        switch(AV_RB32(start)){
 
58
        case VC1_CODE_SEQHDR:
 
59
            vc1_decode_sequence_header(avctx, &vpc->v, &gb);
 
60
            break;
 
61
        case VC1_CODE_ENTRYPOINT:
 
62
            vc1_decode_entry_point(avctx, &vpc->v, &gb);
 
63
            break;
 
64
        case VC1_CODE_FRAME:
 
65
            if(vpc->v.profile < PROFILE_ADVANCED)
 
66
                vc1_parse_frame_header    (&vpc->v, &gb);
 
67
            else
 
68
                vc1_parse_frame_header_adv(&vpc->v, &gb);
 
69
 
 
70
            /* keep FF_BI_TYPE internal to VC1 */
 
71
            if (vpc->v.s.pict_type == FF_BI_TYPE)
 
72
                s->pict_type = FF_B_TYPE;
 
73
            else
 
74
                s->pict_type = vpc->v.s.pict_type;
 
75
 
 
76
            break;
 
77
        }
 
78
    }
 
79
 
 
80
    av_free(buf2);
 
81
}
 
82
 
 
83
/**
 
84
 * finds the end of the current frame in the bitstream.
 
85
 * @return the position of the first byte of the next frame, or -1
 
86
 */
 
87
static int vc1_find_frame_end(ParseContext *pc, const uint8_t *buf,
 
88
                               int buf_size) {
 
89
    int pic_found, i;
 
90
    uint32_t state;
 
91
 
 
92
    pic_found= pc->frame_start_found;
 
93
    state= pc->state;
 
94
 
 
95
    i=0;
 
96
    if(!pic_found){
 
97
        for(i=0; i<buf_size; i++){
 
98
            state= (state<<8) | buf[i];
 
99
            if(state == VC1_CODE_FRAME || state == VC1_CODE_FIELD){
 
100
                i++;
 
101
                pic_found=1;
 
102
                break;
 
103
            }
 
104
        }
 
105
    }
 
106
 
 
107
    if(pic_found){
 
108
        /* EOF considered as end of frame */
 
109
        if (buf_size == 0)
 
110
            return 0;
 
111
        for(; i<buf_size; i++){
 
112
            state= (state<<8) | buf[i];
 
113
            if(IS_MARKER(state) && state != VC1_CODE_FIELD && state != VC1_CODE_SLICE){
 
114
                pc->frame_start_found=0;
 
115
                pc->state=-1;
 
116
                return i-3;
 
117
            }
 
118
        }
 
119
    }
 
120
    pc->frame_start_found= pic_found;
 
121
    pc->state= state;
 
122
    return END_NOT_FOUND;
 
123
}
 
124
 
 
125
static int vc1_parse(AVCodecParserContext *s,
 
126
                           AVCodecContext *avctx,
 
127
                           const uint8_t **poutbuf, int *poutbuf_size,
 
128
                           const uint8_t *buf, int buf_size)
 
129
{
 
130
    VC1ParseContext *vpc = s->priv_data;
 
131
    int next;
 
132
 
 
133
    if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){
 
134
        next= buf_size;
 
135
    }else{
 
136
        next= vc1_find_frame_end(&vpc->pc, buf, buf_size);
 
137
 
 
138
        if (ff_combine_frame(&vpc->pc, next, &buf, &buf_size) < 0) {
 
139
            *poutbuf = NULL;
 
140
            *poutbuf_size = 0;
 
141
            return buf_size;
 
142
        }
 
143
    }
 
144
 
 
145
    vc1_extract_headers(s, avctx, buf, buf_size);
 
146
 
 
147
    *poutbuf = buf;
 
148
    *poutbuf_size = buf_size;
 
149
    return next;
 
150
}
 
151
 
 
152
static int vc1_split(AVCodecContext *avctx,
 
153
                           const uint8_t *buf, int buf_size)
 
154
{
 
155
    int i;
 
156
    uint32_t state= -1;
 
157
    int charged=0;
 
158
 
 
159
    for(i=0; i<buf_size; i++){
 
160
        state= (state<<8) | buf[i];
 
161
        if(IS_MARKER(state)){
 
162
            if(state == VC1_CODE_SEQHDR || state == VC1_CODE_ENTRYPOINT){
 
163
                charged=1;
 
164
            }else if(charged){
 
165
                return i-3;
 
166
            }
 
167
        }
 
168
    }
 
169
    return 0;
 
170
}
 
171
 
 
172
AVCodecParser vc1_parser = {
 
173
    { CODEC_ID_VC1 },
 
174
    sizeof(VC1ParseContext),
 
175
    NULL,
 
176
    vc1_parse,
 
177
    ff_parse1_close,
 
178
    vc1_split,
 
179
};