annotate dirac_parser.c @ 12530:63edd10ad4bc libavcodec tip

Try to fix crashes introduced by r25218 r25218 made assumptions about the existence of past reference frames that weren't necessarily true.
author darkshikari
date Tue, 28 Sep 2010 09:06:22 +0000
parents fdafbcef52f5
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
6733
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
1 /*
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
2 * Dirac parser
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
3 *
8422
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
4 * Copyright (c) 2007-2008 Marco Gerards <marco@gnu.org>
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
5 * Copyright (c) 2008 BBC, Anuradha Suraparaju <asuraparaju@gmail.com>
6733
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
6 *
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
7 * This file is part of FFmpeg.
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
8 *
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
9 * FFmpeg is free software; you can redistribute it and/or
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
10 * modify it under the terms of the GNU Lesser General Public
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
11 * License as published by the Free Software Foundation; either
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
12 * version 2.1 of the License, or (at your option) any later version.
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
13 *
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
14 * FFmpeg is distributed in the hope that it will be useful,
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
17 * Lesser General Public License for more details.
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
18 *
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
19 * You should have received a copy of the GNU Lesser General Public
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
20 * License along with FFmpeg; if not, write to the Free Software
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
22 */
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
23
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
24 /**
11644
7dd2a45249a9 Remove explicit filename from Doxygen @file commands.
diego
parents: 8718
diff changeset
25 * @file
6733
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
26 * Dirac Parser
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
27 * @author Marco Gerards <marco@gnu.org>
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
28 */
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
29
8573
2acf0ae7b041 Fix build: Add intreadwrite.h and bswap.h #includes where necessary.
diego
parents: 8422
diff changeset
30 #include "libavutil/intreadwrite.h"
6733
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
31 #include "parser.h"
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
32
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
33 #define DIRAC_PARSE_INFO_PREFIX 0x42424344
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
34
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
35 /**
12024
fdafbcef52f5 Fix grammar errors in documentation
mru
parents: 11644
diff changeset
36 * Find the end of the current frame in the bitstream.
6733
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
37 * @return the position of the first byte of the next frame or -1
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
38 */
8422
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
39 typedef struct DiracParseContext {
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
40 int state;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
41 int is_synced;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
42 int sync_offset;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
43 int header_bytes_needed;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
44 int overread_index;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
45 int buffer_size;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
46 int index;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
47 uint8_t *buffer;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
48 int dirac_unit_size;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
49 uint8_t *dirac_unit;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
50 } DiracParseContext;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
51
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
52 static int find_frame_end(DiracParseContext *pc,
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
53 const uint8_t *buf, int buf_size)
6733
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
54 {
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
55 uint32_t state = pc->state;
8422
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
56 int i = 0;
6733
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
57
8422
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
58 if (!pc->is_synced) {
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
59 for (i = 0; i < buf_size; i++) {
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
60 state = (state << 8) | buf[i];
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
61 if (state == DIRAC_PARSE_INFO_PREFIX) {
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
62 state = -1;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
63 pc->is_synced = 1;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
64 pc->header_bytes_needed = 9;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
65 pc->sync_offset = i;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
66 break;
6733
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
67 }
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
68 }
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
69 }
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
70
8422
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
71 if (pc->is_synced) {
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
72 pc->sync_offset = 0;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
73 for (; i < buf_size; i++) {
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
74 if (state == DIRAC_PARSE_INFO_PREFIX) {
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
75 if ((buf_size-i) >= pc->header_bytes_needed) {
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
76 pc->state = -1;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
77 return i + pc->header_bytes_needed;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
78 } else {
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
79 pc->header_bytes_needed = 9-(buf_size-i);
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
80 break;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
81 }
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
82 } else
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
83 state = (state << 8) | buf[i];
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
84 }
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
85 }
6733
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
86 pc->state = state;
8422
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
87 return -1;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
88 }
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
89
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
90 typedef struct DiracParseUnit
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
91 {
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
92 int next_pu_offset;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
93 int prev_pu_offset;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
94 uint8_t pu_type;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
95 } DiracParseUnit;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
96
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
97 static int unpack_parse_unit(DiracParseUnit *pu, DiracParseContext *pc,
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
98 int offset)
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
99 {
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
100 uint8_t *start = pc->buffer + offset;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
101 uint8_t *end = pc->buffer + pc->index;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
102 if (start < pc->buffer || (start+13 > end))
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
103 return 0;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
104 pu->pu_type = start[4];
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
105
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
106 pu->next_pu_offset = AV_RB32(start+5);
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
107 pu->prev_pu_offset = AV_RB32(start+9);
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
108
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
109 if (pu->pu_type == 0x10 && pu->next_pu_offset == 0)
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
110 pu->next_pu_offset = 13;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
111
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
112 return 1;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
113 }
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
114
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
115 static int dirac_combine_frame(AVCodecParserContext *s, AVCodecContext *avctx,
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
116 int next, const uint8_t **buf, int *buf_size)
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
117 {
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
118 int parse_timing_info = (s->pts == AV_NOPTS_VALUE &&
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
119 s->dts == AV_NOPTS_VALUE);
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
120 DiracParseContext *pc = s->priv_data;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
121
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
122 if (pc->overread_index) {
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
123 memcpy(pc->buffer, pc->buffer + pc->overread_index,
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
124 pc->index - pc->overread_index);
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
125 pc->index -= pc->overread_index;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
126 pc->overread_index = 0;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
127 if (*buf_size == 0 && pc->buffer[4] == 0x10) {
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
128 *buf = pc->buffer;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
129 *buf_size = pc->index;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
130 return 0;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
131 }
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
132 }
6733
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
133
8422
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
134 if ( next == -1) {
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
135 /* Found a possible frame start but not a frame end */
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
136 void *new_buffer = av_fast_realloc(pc->buffer, &pc->buffer_size,
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
137 pc->index + (*buf_size -
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
138 pc->sync_offset));
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
139 pc->buffer = new_buffer;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
140 memcpy(pc->buffer+pc->index, (*buf + pc->sync_offset),
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
141 *buf_size - pc->sync_offset);
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
142 pc->index += *buf_size - pc->sync_offset;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
143 return -1;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
144 } else {
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
145 /* Found a possible frame start and a possible frame end */
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
146 DiracParseUnit pu1, pu;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
147 void *new_buffer = av_fast_realloc(pc->buffer, &pc->buffer_size,
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
148 pc->index + next);
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
149 pc->buffer = new_buffer;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
150 memcpy(pc->buffer + pc->index, *buf, next);
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
151 pc->index += next;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
152
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
153 /* Need to check if we have a valid Parse Unit. We can't go by the
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
154 * sync pattern 'BBCD' alone because arithmetic coding of the residual
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
155 * and motion data can cause the pattern triggering a false start of
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
156 * frame. So check if the previous parse offset of the next parse unit
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
157 * is equal to the next parse offset of the current parse unit then
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
158 * we can be pretty sure that we have a valid parse unit */
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
159 if (!unpack_parse_unit(&pu1, pc, pc->index - 13) ||
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
160 !unpack_parse_unit(&pu, pc, pc->index - 13 - pu1.prev_pu_offset) ||
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
161 pu.next_pu_offset != pu1.prev_pu_offset) {
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
162 pc->index -= 9;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
163 *buf_size = next-9;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
164 pc->header_bytes_needed = 9;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
165 return -1;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
166 }
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
167
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
168 /* All non-frame data must be accompanied by frame data. This is to
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
169 * ensure that pts is set correctly. So if the current parse unit is
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
170 * not frame data, wait for frame data to come along */
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
171
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
172 pc->dirac_unit = pc->buffer + pc->index - 13 -
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
173 pu1.prev_pu_offset - pc->dirac_unit_size;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
174
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
175 pc->dirac_unit_size += pu.next_pu_offset;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
176
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
177 if ((pu.pu_type&0x08) != 0x08) {
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
178 pc->header_bytes_needed = 9;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
179 *buf_size = next;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
180 return -1;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
181 }
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
182
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
183 /* Get the picture number to set the pts and dts*/
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
184 if (parse_timing_info) {
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
185 uint8_t *cur_pu = pc->buffer +
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
186 pc->index - 13 - pu1.prev_pu_offset;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
187 int pts = AV_RB32(cur_pu + 13);
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
188 if (s->last_pts == 0 && s->last_dts == 0)
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
189 s->dts = pts - 1;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
190 else
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
191 s->dts = s->last_dts+1;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
192 s->pts = pts;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
193 if (!avctx->has_b_frames && (cur_pu[4] & 0x03))
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
194 avctx->has_b_frames = 1;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
195 }
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
196 if (avctx->has_b_frames && s->pts == s->dts)
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
197 s->pict_type = FF_B_TYPE;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
198
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
199 /* Finally have a complete Dirac data unit */
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
200 *buf = pc->dirac_unit;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
201 *buf_size = pc->dirac_unit_size;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
202
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
203 pc->dirac_unit_size = 0;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
204 pc->overread_index = pc->index-13;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
205 pc->header_bytes_needed = 9;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
206 }
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
207 return next;
6733
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
208 }
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
209
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
210 static int dirac_parse(AVCodecParserContext *s, AVCodecContext *avctx,
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
211 const uint8_t **poutbuf, int *poutbuf_size,
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
212 const uint8_t *buf, int buf_size)
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
213 {
8422
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
214 DiracParseContext *pc = s->priv_data;
6733
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
215 int next;
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
216
8422
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
217 *poutbuf = NULL;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
218 *poutbuf_size = 0;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
219
6733
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
220 if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) {
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
221 next = buf_size;
8422
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
222 *poutbuf = buf;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
223 *poutbuf_size = buf_size;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
224 /* Assume that data has been packetized into an encapsulation unit. */
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
225 } else {
6733
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
226 next = find_frame_end(pc, buf, buf_size);
8422
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
227 if (!pc->is_synced && next == -1) {
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
228 /* No frame start found yet. So throw away the entire buffer. */
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
229 return buf_size;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
230 }
6733
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
231
8422
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
232 if (dirac_combine_frame(s, avctx, next, &buf, &buf_size) < 0) {
6733
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
233 return buf_size;
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
234 }
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
235 }
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
236
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
237 *poutbuf = buf;
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
238 *poutbuf_size = buf_size;
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
239 return next;
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
240 }
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
241
8422
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
242 static void dirac_parse_close(AVCodecParserContext *s)
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
243 {
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
244 DiracParseContext *pc = s->priv_data;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
245
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
246 if (pc->buffer_size > 0)
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
247 av_free(pc->buffer);
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
248 }
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
249
6733
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
250 AVCodecParser dirac_parser = {
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
251 { CODEC_ID_DIRAC },
8422
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
252 sizeof(DiracParseContext),
6733
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
253 NULL,
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
254 dirac_parse,
8422
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
255 dirac_parse_close,
6733
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
256 };