Mercurial > libavcodec.hg
annotate dirac_parser.c @ 10061:09f2db2d7c90 libavcodec
Fix bug caused by difference in stride and picture width.
When a frame is allocated using libschroedinger routines, the frame data size
does not match the actual frame size if the width is not a multiple of 16. So
we cannot do a straightforward memcpy of the frame returned by libschroedinger
into the FFmpeg picture as the stride differs from the width.
Fix this bug by allocating for the libschroedinger frame with the dimensions
in AVCodecContext within libavcodec and passing the frame to libschroedinger.
patch by Anuradha Suraparaju, anuradha rd.bbc.co uk
author | diego |
---|---|
date | Sat, 15 Aug 2009 11:59:53 +0000 |
parents | e9d9d946f213 |
children | 7dd2a45249a9 |
rev | line source |
---|---|
6733 | 1 /* |
2 * Dirac parser | |
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 | 6 * |
7 * This file is part of FFmpeg. | |
8 * | |
9 * FFmpeg is free software; you can redistribute it and/or | |
10 * modify it under the terms of the GNU Lesser General Public | |
11 * License as published by the Free Software Foundation; either | |
12 * version 2.1 of the License, or (at your option) any later version. | |
13 * | |
14 * FFmpeg is distributed in the hope that it will be useful, | |
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
17 * Lesser General Public License for more details. | |
18 * | |
19 * You should have received a copy of the GNU Lesser General Public | |
20 * License along with FFmpeg; if not, write to the Free Software | |
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
22 */ | |
23 | |
24 /** | |
8718
e9d9d946f213
Use full internal pathname in doxygen @file directives.
diego
parents:
8573
diff
changeset
|
25 * @file libavcodec/dirac_parser.c |
6733 | 26 * Dirac Parser |
27 * @author Marco Gerards <marco@gnu.org> | |
28 */ | |
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 | 31 #include "parser.h" |
32 | |
33 #define DIRAC_PARSE_INFO_PREFIX 0x42424344 | |
34 | |
35 /** | |
36 * Finds the end of the current frame in the bitstream. | |
37 * @return the position of the first byte of the next frame or -1 | |
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 | 54 { |
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 | 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 | 67 } |
68 } | |
69 } | |
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 | 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 | 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 | 208 } |
209 | |
210 static int dirac_parse(AVCodecParserContext *s, AVCodecContext *avctx, | |
211 const uint8_t **poutbuf, int *poutbuf_size, | |
212 const uint8_t *buf, int buf_size) | |
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 | 215 int next; |
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 | 220 if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) { |
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 | 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 | 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 | 233 return buf_size; |
234 } | |
235 } | |
236 | |
237 *poutbuf = buf; | |
238 *poutbuf_size = buf_size; | |
239 return next; | |
240 } | |
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 | 250 AVCodecParser dirac_parser = { |
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 | 253 NULL, |
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 | 256 }; |