GCC Code Coverage Report
Directory: ../../../ffmpeg/ Exec Total Coverage
File: src/libavcodec/dnxhd_parser.c Lines: 66 70 94.3 %
Date: 2019-11-18 18:00:01 Branches: 31 36 86.1 %

Line Branch Exec Source
1
/*
2
 * DNxHD/VC-3 parser
3
 * Copyright (c) 2008 Baptiste Coudurier <baptiste.coudurier@free.fr>
4
 *
5
 * This file is part of FFmpeg.
6
 *
7
 * FFmpeg is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
11
 *
12
 * FFmpeg is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with FFmpeg; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
 */
21
22
/**
23
 * @file
24
 * DNxHD/VC-3 parser
25
 */
26
27
#include "parser.h"
28
#include "dnxhddata.h"
29
30
typedef struct {
31
    ParseContext pc;
32
    int cur_byte;
33
    int remaining;
34
    int w, h;
35
} DNXHDParserContext;
36
37
177532
static int dnxhd_find_frame_end(DNXHDParserContext *dctx,
38
                                const uint8_t *buf, int buf_size)
39
{
40
177532
    ParseContext *pc = &dctx->pc;
41
177532
    uint64_t state = pc->state64;
42
177532
    int pic_found = pc->frame_start_found;
43
177532
    int i = 0;
44
45
177532
    if (!pic_found) {
46
2630
        for (i = 0; i < buf_size; i++) {
47
2526
            state = (state << 8) | buf[i];
48
2526
            if (ff_dnxhd_check_header_prefix(state & 0xffffffffff00LL) != 0) {
49
421
                i++;
50
421
                pic_found = 1;
51
421
                dctx->cur_byte = 0;
52
421
                dctx->remaining = 0;
53
421
                break;
54
            }
55
        }
56
    }
57
58

177532
    if (pic_found && !dctx->remaining) {
59
421
        if (!buf_size) /* EOF considered as end of frame */
60
            return 0;
61
17682
        for (; i < buf_size; i++) {
62
17682
            dctx->cur_byte++;
63
17682
            state = (state << 8) | buf[i];
64
65
17682
            if (dctx->cur_byte == 24) {
66
421
                dctx->h = (state >> 32) & 0xFFFF;
67
17261
            } else if (dctx->cur_byte == 26) {
68
421
                dctx->w = (state >> 32) & 0xFFFF;
69
16840
            } else if (dctx->cur_byte == 42) {
70
421
                int cid = (state >> 32) & 0xFFFFFFFF;
71
                int remaining;
72
73
421
                if (cid <= 0)
74
                    continue;
75
76
421
                remaining = avpriv_dnxhd_get_frame_size(cid);
77
421
                if (remaining <= 0) {
78
218
                    remaining = avpriv_dnxhd_get_hr_frame_size(cid, dctx->w, dctx->h);
79
218
                    if (remaining <= 0)
80
                        continue;
81
                }
82
421
                remaining += i - 47;
83
421
                dctx->remaining = remaining;
84
421
                if (buf_size >= dctx->remaining) {
85
84
                    pc->frame_start_found = 0;
86
84
                    pc->state64 = -1;
87
84
                    dctx->cur_byte = 0;
88
84
                    dctx->remaining = 0;
89
84
                    return remaining;
90
                } else {
91
337
                    dctx->remaining -= buf_size;
92
                    // Update variables for correctness, they are currently not used beyond here
93
337
                    state = -1;
94
337
                    dctx->cur_byte += buf_size - i;
95
337
                    break;
96
                }
97
            }
98
        }
99
177111
    } else if (pic_found) {
100
177007
        if (dctx->remaining > buf_size) {
101
176670
            dctx->remaining -= buf_size;
102
        } else {
103
337
            int remaining = dctx->remaining;
104
105
337
            pc->frame_start_found = 0;
106
337
            pc->state64 = -1;
107
337
            dctx->cur_byte = 0;
108
337
            dctx->remaining = 0;
109
337
            return remaining;
110
        }
111
    }
112
177111
    pc->frame_start_found = pic_found;
113
177111
    pc->state64 = state;
114
177111
    return END_NOT_FOUND;
115
}
116
117
177532
static int dnxhd_parse(AVCodecParserContext *s,
118
                       AVCodecContext *avctx,
119
                       const uint8_t **poutbuf, int *poutbuf_size,
120
                       const uint8_t *buf, int buf_size)
121
{
122
177532
    DNXHDParserContext *dctx = s->priv_data;
123
177532
    ParseContext *pc = &dctx->pc;
124
    int next;
125
126
177532
    if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) {
127
        next = buf_size;
128
    } else {
129
177532
        next = dnxhd_find_frame_end(dctx, buf, buf_size);
130
177532
        if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
131
177007
            *poutbuf      = NULL;
132
177007
            *poutbuf_size = 0;
133
177007
            return buf_size;
134
        }
135
    }
136
525
    *poutbuf      = buf;
137
525
    *poutbuf_size = buf_size;
138
525
    return next;
139
}
140
141
AVCodecParser ff_dnxhd_parser = {
142
    .codec_ids      = { AV_CODEC_ID_DNXHD },
143
    .priv_data_size = sizeof(DNXHDParserContext),
144
    .parser_parse   = dnxhd_parse,
145
    .parser_close   = ff_parse_close,
146
};