Statistics
| Branch: | Revision:

ffmpeg / libavcodec / dca_parser.c @ c53d2d90

History | View | Annotate | Download (3.6 KB)

1
/*
2
 * DCA parser
3
 * Copyright (C) 2004 Gildas Bazin
4
 * Copyright (C) 2004 Benjamin Zores
5
 * Copyright (C) 2006 Benjamin Larsson
6
 * Copyright (C) 2007 Konstantin Shishkov
7
 *
8
 * This file is part of FFmpeg.
9
 *
10
 * FFmpeg is free software; you can redistribute it and/or
11
 * modify it under the terms of the GNU Lesser General Public
12
 * License as published by the Free Software Foundation; either
13
 * version 2.1 of the License, or (at your option) any later version.
14
 *
15
 * FFmpeg is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18
 * Lesser General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU Lesser General Public
21
 * License along with FFmpeg; if not, write to the Free Software
22
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23
 */
24

    
25
/**
26
 * @file dca_parser.c
27
 */
28

    
29
#include "parser.h"
30
#include "dca.h"
31

    
32
typedef struct DCAParseContext {
33
    ParseContext pc;
34
    uint32_t lastmarker;
35
} DCAParseContext;
36

    
37
#define IS_MARKER(state, i, buf, buf_size) \
38
 ((state == DCA_MARKER_14B_LE && (i < buf_size-2) && (buf[i+1] & 0xF0) == 0xF0 && buf[i+2] == 0x07) \
39
 || (state == DCA_MARKER_14B_BE && (i < buf_size-2) && buf[i+1] == 0x07 && (buf[i+2] & 0xF0) == 0xF0) \
40
 || state == DCA_MARKER_RAW_LE || state == DCA_MARKER_RAW_BE)
41

    
42
/**
43
 * finds the end of the current frame in the bitstream.
44
 * @return the position of the first byte of the next frame, or -1
45
 */
46
static int dca_find_frame_end(DCAParseContext * pc1, const uint8_t * buf,
47
                              int buf_size)
48
{
49
    int start_found, i;
50
    uint32_t state;
51
    ParseContext *pc = &pc1->pc;
52

    
53
    start_found = pc->frame_start_found;
54
    state = pc->state;
55

    
56
    i = 0;
57
    if (!start_found) {
58
        for (i = 0; i < buf_size; i++) {
59
            state = (state << 8) | buf[i];
60
            if (IS_MARKER(state, i, buf, buf_size)) {
61
                if (pc1->lastmarker && state == pc1->lastmarker) {
62
                    start_found = 1;
63
                    break;
64
                } else if (!pc1->lastmarker) {
65
                    start_found = 1;
66
                    pc1->lastmarker = state;
67
                    break;
68
                }
69
            }
70
        }
71
    }
72
    if (start_found) {
73
        for (; i < buf_size; i++) {
74
            state = (state << 8) | buf[i];
75
            if (state == pc1->lastmarker && IS_MARKER(state, i, buf, buf_size)) {
76
                pc->frame_start_found = 0;
77
                pc->state = -1;
78
                return i - 3;
79
            }
80
        }
81
    }
82
    pc->frame_start_found = start_found;
83
    pc->state = state;
84
    return END_NOT_FOUND;
85
}
86

    
87
static int dca_parse_init(AVCodecParserContext * s)
88
{
89
    DCAParseContext *pc1 = s->priv_data;
90

    
91
    pc1->lastmarker = 0;
92
    return 0;
93
}
94

    
95
static int dca_parse(AVCodecParserContext * s,
96
                     AVCodecContext * avctx,
97
                     const uint8_t ** poutbuf, int *poutbuf_size,
98
                     const uint8_t * buf, int buf_size)
99
{
100
    DCAParseContext *pc1 = s->priv_data;
101
    ParseContext *pc = &pc1->pc;
102
    int next;
103

    
104
    if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) {
105
        next = buf_size;
106
    } else {
107
        next = dca_find_frame_end(pc1, buf, buf_size);
108

    
109
        if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
110
            *poutbuf = NULL;
111
            *poutbuf_size = 0;
112
            return buf_size;
113
        }
114
    }
115
    *poutbuf = buf;
116
    *poutbuf_size = buf_size;
117
    return next;
118
}
119

    
120
AVCodecParser dca_parser = {
121
    {CODEC_ID_DTS},
122
    sizeof(DCAParseContext),
123
    dca_parse_init,
124
    dca_parse,
125
    ff_parse_close,
126
};