annotate dirac_parser.c @ 8520:a0164882aa38 libavcodec

Generic metadata API. avi is updated as example. No version bump, the API still might change slightly ... No update to ffmpeg.c as requested by aurel.
author michael
date Sun, 04 Jan 2009 18:48:37 +0000
parents e623323d409f
children 2acf0ae7b041
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 /**
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
25 * @file dirac_parser.c
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
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
30 #include "parser.h"
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
31
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
32 #define DIRAC_PARSE_INFO_PREFIX 0x42424344
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
33
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 * Finds the end of the current frame in the bitstream.
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
36 * @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
37 */
8422
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
38 typedef struct DiracParseContext {
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
39 int state;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
40 int is_synced;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
41 int sync_offset;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
42 int header_bytes_needed;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
43 int overread_index;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
44 int buffer_size;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
45 int index;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
46 uint8_t *buffer;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
47 int dirac_unit_size;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
48 uint8_t *dirac_unit;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
49 } DiracParseContext;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
50
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
51 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
52 const uint8_t *buf, int buf_size)
6733
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
53 {
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
54 uint32_t state = pc->state;
8422
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
55 int i = 0;
6733
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
56
8422
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
57 if (!pc->is_synced) {
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
58 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
59 state = (state << 8) | buf[i];
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
60 if (state == DIRAC_PARSE_INFO_PREFIX) {
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
61 state = -1;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
62 pc->is_synced = 1;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
63 pc->header_bytes_needed = 9;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
64 pc->sync_offset = i;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
65 break;
6733
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
66 }
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
8422
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
70 if (pc->is_synced) {
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
71 pc->sync_offset = 0;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
72 for (; i < buf_size; i++) {
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
73 if (state == DIRAC_PARSE_INFO_PREFIX) {
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
74 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
75 pc->state = -1;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
76 return i + pc->header_bytes_needed;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
77 } else {
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
78 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
79 break;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
80 }
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
81 } else
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
82 state = (state << 8) | buf[i];
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
83 }
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
84 }
6733
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
85 pc->state = state;
8422
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
86 return -1;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
87 }
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 typedef struct DiracParseUnit
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
90 {
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
91 int next_pu_offset;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
92 int prev_pu_offset;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
93 uint8_t pu_type;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
94 } DiracParseUnit;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
95
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
96 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
97 int offset)
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
98 {
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
99 uint8_t *start = pc->buffer + offset;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
100 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
101 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
102 return 0;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
103 pu->pu_type = start[4];
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
104
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
105 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
106 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
107
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
108 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
109 pu->next_pu_offset = 13;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
110
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
111 return 1;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
112 }
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 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
115 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
116 {
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
117 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
118 s->dts == AV_NOPTS_VALUE);
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
119 DiracParseContext *pc = s->priv_data;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
120
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
121 if (pc->overread_index) {
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
122 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
123 pc->index - 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->overread_index = 0;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
126 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
127 *buf = pc->buffer;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
128 *buf_size = pc->index;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
129 return 0;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
130 }
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
131 }
6733
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
132
8422
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
133 if ( next == -1) {
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
134 /* 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
135 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
136 pc->index + (*buf_size -
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
137 pc->sync_offset));
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
138 pc->buffer = new_buffer;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
139 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
140 *buf_size - pc->sync_offset);
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
141 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
142 return -1;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
143 } else {
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
144 /* 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
145 DiracParseUnit pu1, pu;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
146 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
147 pc->index + next);
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
148 pc->buffer = new_buffer;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
149 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
150 pc->index += next;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
151
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
152 /* 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
153 * 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
154 * 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
155 * 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
156 * 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
157 * 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
158 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
159 !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
160 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
161 pc->index -= 9;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
162 *buf_size = next-9;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
163 pc->header_bytes_needed = 9;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
164 return -1;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
165 }
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 /* 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
168 * 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
169 * 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
170
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
171 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
172 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
173
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
174 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
175
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
176 if ((pu.pu_type&0x08) != 0x08) {
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
177 pc->header_bytes_needed = 9;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
178 *buf_size = next;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
179 return -1;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
180 }
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 /* 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
183 if (parse_timing_info) {
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
184 uint8_t *cur_pu = pc->buffer +
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
185 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
186 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
187 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
188 s->dts = pts - 1;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
189 else
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
190 s->dts = s->last_dts+1;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
191 s->pts = pts;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
192 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
193 avctx->has_b_frames = 1;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
194 }
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
195 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
196 s->pict_type = FF_B_TYPE;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
197
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
198 /* 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
199 *buf = pc->dirac_unit;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
200 *buf_size = pc->dirac_unit_size;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
201
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
202 pc->dirac_unit_size = 0;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
203 pc->overread_index = pc->index-13;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
204 pc->header_bytes_needed = 9;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
205 }
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
206 return next;
6733
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
207 }
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 static int dirac_parse(AVCodecParserContext *s, AVCodecContext *avctx,
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
210 const uint8_t **poutbuf, int *poutbuf_size,
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
211 const uint8_t *buf, int buf_size)
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
212 {
8422
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
213 DiracParseContext *pc = s->priv_data;
6733
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
214 int next;
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
215
8422
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
216 *poutbuf = NULL;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
217 *poutbuf_size = 0;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
218
6733
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
219 if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) {
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
220 next = buf_size;
8422
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
221 *poutbuf = buf;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
222 *poutbuf_size = buf_size;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
223 /* 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
224 } else {
6733
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
225 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
226 if (!pc->is_synced && next == -1) {
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
227 /* 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
228 return buf_size;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
229 }
6733
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
230
8422
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
231 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
232 return buf_size;
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
233 }
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 *poutbuf = buf;
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
237 *poutbuf_size = buf_size;
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
238 return next;
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
239 }
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
240
8422
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
241 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
242 {
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
243 DiracParseContext *pc = s->priv_data;
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
244
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
245 if (pc->buffer_size > 0)
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
246 av_free(pc->buffer);
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
247 }
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
248
6733
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
249 AVCodecParser dirac_parser = {
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
250 { CODEC_ID_DIRAC },
8422
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
251 sizeof(DiracParseContext),
6733
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
252 NULL,
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
253 dirac_parse,
8422
e623323d409f Fix incorrectly constructed Dirac parse units that caused A/V sync loss.
diego
parents: 6733
diff changeset
254 dirac_parse_close,
6733
cebe9c3422a8 Add Dirac parser from SoC; written by Marco Gerards;
diego
parents:
diff changeset
255 };