annotate parser.c @ 2841:bceeca1bb30f libavcodec

vbr audio encode patch by (Justin Ruggles: jruggle, earthlink net) with changes by me int->float as video uses float too remove silent cliping to some per codec range, this should result in an error instead remove change to utils.c as its inconsistant with video
author michael
date Sun, 21 Aug 2005 20:27:00 +0000
parents 45ccf6842c34
children 40765c51a7a9
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
1 /*
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
2 * Audio and Video frame extraction
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
3 * Copyright (c) 2003 Fabrice Bellard.
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
4 * Copyright (c) 2003 Michael Niedermayer.
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
5 *
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
6 * This library is free software; you can redistribute it and/or
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
7 * modify it under the terms of the GNU Lesser General Public
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
8 * License as published by the Free Software Foundation; either
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
9 * version 2 of the License, or (at your option) any later version.
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
10 *
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
11 * This library is distributed in the hope that it will be useful,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
14 * Lesser General Public License for more details.
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
15 *
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
16 * You should have received a copy of the GNU Lesser General Public
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
17 * License along with this library; if not, write to the Free Software
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
19 */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
20 #include "avcodec.h"
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
21 #include "mpegvideo.h"
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
22 #include "mpegaudio.h"
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
23
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
24 AVCodecParser *av_first_parser = NULL;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
25
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
26 void av_register_codec_parser(AVCodecParser *parser)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
27 {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
28 parser->next = av_first_parser;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
29 av_first_parser = parser;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
30 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
31
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
32 AVCodecParserContext *av_parser_init(int codec_id)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
33 {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
34 AVCodecParserContext *s;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
35 AVCodecParser *parser;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
36 int ret;
2486
f2a9559db6ac 10l (array gets padded with 0 which is CODEC_ID_NONE -> parsers claim to support CODEC_ID_NONE)
michael
parents: 2480
diff changeset
37
f2a9559db6ac 10l (array gets padded with 0 which is CODEC_ID_NONE -> parsers claim to support CODEC_ID_NONE)
michael
parents: 2480
diff changeset
38 if(codec_id == CODEC_ID_NONE)
f2a9559db6ac 10l (array gets padded with 0 which is CODEC_ID_NONE -> parsers claim to support CODEC_ID_NONE)
michael
parents: 2480
diff changeset
39 return NULL;
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
40
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
41 for(parser = av_first_parser; parser != NULL; parser = parser->next) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
42 if (parser->codec_ids[0] == codec_id ||
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
43 parser->codec_ids[1] == codec_id ||
2348
d02fb928ca44 pnm parser
michael
parents: 2270
diff changeset
44 parser->codec_ids[2] == codec_id ||
d02fb928ca44 pnm parser
michael
parents: 2270
diff changeset
45 parser->codec_ids[3] == codec_id ||
d02fb928ca44 pnm parser
michael
parents: 2270
diff changeset
46 parser->codec_ids[4] == codec_id)
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
47 goto found;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
48 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
49 return NULL;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
50 found:
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
51 s = av_mallocz(sizeof(AVCodecParserContext));
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
52 if (!s)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
53 return NULL;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
54 s->parser = parser;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
55 s->priv_data = av_mallocz(parser->priv_data_size);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
56 if (!s->priv_data) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
57 av_free(s);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
58 return NULL;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
59 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
60 if (parser->parser_init) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
61 ret = parser->parser_init(s);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
62 if (ret != 0) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
63 av_free(s->priv_data);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
64 av_free(s);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
65 return NULL;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
66 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
67 }
2030
f796043935f3 mpeg audio timestamp fix
michael
parents: 2024
diff changeset
68 s->fetch_timestamp=1;
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
69 return s;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
70 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
71
1694
13169235c306 added End Of File handling to return last picture for MPEG1/2/4
bellard
parents: 1681
diff changeset
72 /* NOTE: buf_size == 0 is used to signal EOF so that the last frame
13169235c306 added End Of File handling to return last picture for MPEG1/2/4
bellard
parents: 1681
diff changeset
73 can be returned if necessary */
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
74 int av_parser_parse(AVCodecParserContext *s,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
75 AVCodecContext *avctx,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
76 uint8_t **poutbuf, int *poutbuf_size,
1696
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
77 const uint8_t *buf, int buf_size,
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
78 int64_t pts, int64_t dts)
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
79 {
1696
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
80 int index, i, k;
1694
13169235c306 added End Of File handling to return last picture for MPEG1/2/4
bellard
parents: 1681
diff changeset
81 uint8_t dummy_buf[FF_INPUT_BUFFER_PADDING_SIZE];
13169235c306 added End Of File handling to return last picture for MPEG1/2/4
bellard
parents: 1681
diff changeset
82
13169235c306 added End Of File handling to return last picture for MPEG1/2/4
bellard
parents: 1681
diff changeset
83 if (buf_size == 0) {
13169235c306 added End Of File handling to return last picture for MPEG1/2/4
bellard
parents: 1681
diff changeset
84 /* padding is always necessary even if EOF, so we add it here */
13169235c306 added End Of File handling to return last picture for MPEG1/2/4
bellard
parents: 1681
diff changeset
85 memset(dummy_buf, 0, sizeof(dummy_buf));
13169235c306 added End Of File handling to return last picture for MPEG1/2/4
bellard
parents: 1681
diff changeset
86 buf = dummy_buf;
1696
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
87 } else {
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
88 /* add a new packet descriptor */
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
89 k = (s->cur_frame_start_index + 1) & (AV_PARSER_PTS_NB - 1);
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
90 s->cur_frame_start_index = k;
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
91 s->cur_frame_offset[k] = s->cur_offset;
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
92 s->cur_frame_pts[k] = pts;
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
93 s->cur_frame_dts[k] = dts;
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
94
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
95 /* fill first PTS/DTS */
2030
f796043935f3 mpeg audio timestamp fix
michael
parents: 2024
diff changeset
96 if (s->fetch_timestamp){
f796043935f3 mpeg audio timestamp fix
michael
parents: 2024
diff changeset
97 s->fetch_timestamp=0;
1696
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
98 s->last_pts = pts;
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
99 s->last_dts = dts;
2107
bec4623c2201 timestamp duplication bugfix
michael
parents: 2030
diff changeset
100 s->cur_frame_pts[k] =
bec4623c2201 timestamp duplication bugfix
michael
parents: 2030
diff changeset
101 s->cur_frame_dts[k] = AV_NOPTS_VALUE;
1696
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
102 }
1694
13169235c306 added End Of File handling to return last picture for MPEG1/2/4
bellard
parents: 1681
diff changeset
103 }
13169235c306 added End Of File handling to return last picture for MPEG1/2/4
bellard
parents: 1681
diff changeset
104
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
105 /* WARNING: the returned index can be negative */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
106 index = s->parser->parser_parse(s, avctx, poutbuf, poutbuf_size, buf, buf_size);
2107
bec4623c2201 timestamp duplication bugfix
michael
parents: 2030
diff changeset
107 //av_log(NULL, AV_LOG_DEBUG, "parser: in:%lld, %lld, out:%lld, %lld, in:%d out:%d id:%d\n", pts, dts, s->last_pts, s->last_dts, buf_size, *poutbuf_size, avctx->codec_id);
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
108 /* update the file pointer */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
109 if (*poutbuf_size) {
1696
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
110 /* fill the data for the current frame */
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
111 s->frame_offset = s->last_frame_offset;
1696
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
112 s->pts = s->last_pts;
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
113 s->dts = s->last_dts;
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
114
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
115 /* offset of the next frame */
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
116 s->last_frame_offset = s->cur_offset + index;
1696
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
117 /* find the packet in which the new frame starts. It
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
118 is tricky because of MPEG video start codes
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
119 which can begin in one packet and finish in
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
120 another packet. In the worst case, an MPEG
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
121 video start code could be in 4 different
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
122 packets. */
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
123 k = s->cur_frame_start_index;
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
124 for(i = 0; i < AV_PARSER_PTS_NB; i++) {
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
125 if (s->last_frame_offset >= s->cur_frame_offset[k])
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
126 break;
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
127 k = (k - 1) & (AV_PARSER_PTS_NB - 1);
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
128 }
2030
f796043935f3 mpeg audio timestamp fix
michael
parents: 2024
diff changeset
129
1696
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
130 s->last_pts = s->cur_frame_pts[k];
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
131 s->last_dts = s->cur_frame_dts[k];
2030
f796043935f3 mpeg audio timestamp fix
michael
parents: 2024
diff changeset
132
f796043935f3 mpeg audio timestamp fix
michael
parents: 2024
diff changeset
133 /* some parsers tell us the packet size even before seeing the first byte of the next packet,
f796043935f3 mpeg audio timestamp fix
michael
parents: 2024
diff changeset
134 so the next pts/dts is in the next chunk */
f796043935f3 mpeg audio timestamp fix
michael
parents: 2024
diff changeset
135 if(index == buf_size){
f796043935f3 mpeg audio timestamp fix
michael
parents: 2024
diff changeset
136 s->fetch_timestamp=1;
f796043935f3 mpeg audio timestamp fix
michael
parents: 2024
diff changeset
137 }
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
138 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
139 if (index < 0)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
140 index = 0;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
141 s->cur_offset += index;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
142 return index;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
143 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
144
2777
09108466b7d0 off by 1 error bugfix
michael
parents: 2769
diff changeset
145 /**
09108466b7d0 off by 1 error bugfix
michael
parents: 2769
diff changeset
146 *
09108466b7d0 off by 1 error bugfix
michael
parents: 2769
diff changeset
147 * @return 0 if the output buffer is a subset of the input, 1 if it is allocated and must be freed
09108466b7d0 off by 1 error bugfix
michael
parents: 2769
diff changeset
148 */
2769
1394b45a7bf4 support changing in bitstream global headers into extradata style and back
michael
parents: 2637
diff changeset
149 int av_parser_change(AVCodecParserContext *s,
1394b45a7bf4 support changing in bitstream global headers into extradata style and back
michael
parents: 2637
diff changeset
150 AVCodecContext *avctx,
1394b45a7bf4 support changing in bitstream global headers into extradata style and back
michael
parents: 2637
diff changeset
151 uint8_t **poutbuf, int *poutbuf_size,
1394b45a7bf4 support changing in bitstream global headers into extradata style and back
michael
parents: 2637
diff changeset
152 const uint8_t *buf, int buf_size, int keyframe){
1394b45a7bf4 support changing in bitstream global headers into extradata style and back
michael
parents: 2637
diff changeset
153
1394b45a7bf4 support changing in bitstream global headers into extradata style and back
michael
parents: 2637
diff changeset
154 if(s && s->parser->split){
2777
09108466b7d0 off by 1 error bugfix
michael
parents: 2769
diff changeset
155 if((avctx->flags & CODEC_FLAG_GLOBAL_HEADER) || (avctx->flags2 & CODEC_FLAG2_LOCAL_HEADER)){
2769
1394b45a7bf4 support changing in bitstream global headers into extradata style and back
michael
parents: 2637
diff changeset
156 int i= s->parser->split(avctx, buf, buf_size);
1394b45a7bf4 support changing in bitstream global headers into extradata style and back
michael
parents: 2637
diff changeset
157 buf += i;
1394b45a7bf4 support changing in bitstream global headers into extradata style and back
michael
parents: 2637
diff changeset
158 buf_size -= i;
1394b45a7bf4 support changing in bitstream global headers into extradata style and back
michael
parents: 2637
diff changeset
159 }
1394b45a7bf4 support changing in bitstream global headers into extradata style and back
michael
parents: 2637
diff changeset
160 }
1394b45a7bf4 support changing in bitstream global headers into extradata style and back
michael
parents: 2637
diff changeset
161
1394b45a7bf4 support changing in bitstream global headers into extradata style and back
michael
parents: 2637
diff changeset
162 *poutbuf= buf;
1394b45a7bf4 support changing in bitstream global headers into extradata style and back
michael
parents: 2637
diff changeset
163 *poutbuf_size= buf_size;
1394b45a7bf4 support changing in bitstream global headers into extradata style and back
michael
parents: 2637
diff changeset
164 if(avctx->extradata){
1394b45a7bf4 support changing in bitstream global headers into extradata style and back
michael
parents: 2637
diff changeset
165 if( (keyframe && (avctx->flags2 & CODEC_FLAG2_LOCAL_HEADER))
1394b45a7bf4 support changing in bitstream global headers into extradata style and back
michael
parents: 2637
diff changeset
166 /*||(s->pict_type != I_TYPE && (s->flags & PARSER_FLAG_DUMP_EXTRADATA_AT_NOKEY))*/
1394b45a7bf4 support changing in bitstream global headers into extradata style and back
michael
parents: 2637
diff changeset
167 /*||(? && (s->flags & PARSER_FLAG_DUMP_EXTRADATA_AT_BEGIN)*/){
1394b45a7bf4 support changing in bitstream global headers into extradata style and back
michael
parents: 2637
diff changeset
168 int size= buf_size + avctx->extradata_size;
1394b45a7bf4 support changing in bitstream global headers into extradata style and back
michael
parents: 2637
diff changeset
169 *poutbuf_size= size;
1394b45a7bf4 support changing in bitstream global headers into extradata style and back
michael
parents: 2637
diff changeset
170 *poutbuf= av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE);
1394b45a7bf4 support changing in bitstream global headers into extradata style and back
michael
parents: 2637
diff changeset
171
1394b45a7bf4 support changing in bitstream global headers into extradata style and back
michael
parents: 2637
diff changeset
172 memcpy(*poutbuf, avctx->extradata, avctx->extradata_size);
2777
09108466b7d0 off by 1 error bugfix
michael
parents: 2769
diff changeset
173 memcpy((*poutbuf) + avctx->extradata_size, buf, buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
2769
1394b45a7bf4 support changing in bitstream global headers into extradata style and back
michael
parents: 2637
diff changeset
174 return 1;
1394b45a7bf4 support changing in bitstream global headers into extradata style and back
michael
parents: 2637
diff changeset
175 }
1394b45a7bf4 support changing in bitstream global headers into extradata style and back
michael
parents: 2637
diff changeset
176 }
1394b45a7bf4 support changing in bitstream global headers into extradata style and back
michael
parents: 2637
diff changeset
177
1394b45a7bf4 support changing in bitstream global headers into extradata style and back
michael
parents: 2637
diff changeset
178 return 0;
1394b45a7bf4 support changing in bitstream global headers into extradata style and back
michael
parents: 2637
diff changeset
179 }
1394b45a7bf4 support changing in bitstream global headers into extradata style and back
michael
parents: 2637
diff changeset
180
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
181 void av_parser_close(AVCodecParserContext *s)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
182 {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
183 if (s->parser->parser_close)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
184 s->parser->parser_close(s);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
185 av_free(s->priv_data);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
186 av_free(s);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
187 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
188
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
189 /*****************************************************/
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
190
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
191 //#define END_NOT_FOUND (-100)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
192
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
193 #define PICTURE_START_CODE 0x00000100
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
194 #define SEQ_START_CODE 0x000001b3
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
195 #define EXT_START_CODE 0x000001b5
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
196 #define SLICE_MIN_START_CODE 0x00000101
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
197 #define SLICE_MAX_START_CODE 0x000001af
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
198
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
199 typedef struct ParseContext1{
1988
b5753525f9a8 remove duplicated find_frame_end() code
michael
parents: 1987
diff changeset
200 ParseContext pc;
b5753525f9a8 remove duplicated find_frame_end() code
michael
parents: 1987
diff changeset
201 /* XXX/FIXME PC1 vs. PC */
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
202 /* MPEG2 specific */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
203 int frame_rate;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
204 int progressive_sequence;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
205 int width, height;
1614
6c82ef97d3e6 also parse extradata for MPEG4
bellard
parents: 1613
diff changeset
206
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
207 /* XXX: suppress that, needed by MPEG4 */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
208 MpegEncContext *enc;
1614
6c82ef97d3e6 also parse extradata for MPEG4
bellard
parents: 1613
diff changeset
209 int first_picture;
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
210 } ParseContext1;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
211
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
212 /**
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
213 * combines the (truncated) bitstream to a complete frame
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
214 * @returns -1 if no complete frame could be created
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
215 */
1988
b5753525f9a8 remove duplicated find_frame_end() code
michael
parents: 1987
diff changeset
216 int ff_combine_frame(ParseContext *pc, int next, uint8_t **buf, int *buf_size)
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
217 {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
218 #if 0
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
219 if(pc->overread){
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
220 printf("overread %d, state:%X next:%d index:%d o_index:%d\n", pc->overread, pc->state, next, pc->index, pc->overread_index);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
221 printf("%X %X %X %X\n", (*buf)[0], (*buf)[1],(*buf)[2],(*buf)[3]);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
222 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
223 #endif
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
224
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
225 /* copy overreaded bytes from last frame into buffer */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
226 for(; pc->overread>0; pc->overread--){
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
227 pc->buffer[pc->index++]= pc->buffer[pc->overread_index++];
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
228 }
2386
8d1983254e28 flush remaining data from parser at EOF
michael
parents: 2348
diff changeset
229
8d1983254e28 flush remaining data from parser at EOF
michael
parents: 2348
diff changeset
230 /* flush remaining if EOF */
8d1983254e28 flush remaining data from parser at EOF
michael
parents: 2348
diff changeset
231 if(!*buf_size && next == END_NOT_FOUND){
8d1983254e28 flush remaining data from parser at EOF
michael
parents: 2348
diff changeset
232 next= 0;
8d1983254e28 flush remaining data from parser at EOF
michael
parents: 2348
diff changeset
233 }
8d1983254e28 flush remaining data from parser at EOF
michael
parents: 2348
diff changeset
234
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
235 pc->last_index= pc->index;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
236
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
237 /* copy into buffer end return */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
238 if(next == END_NOT_FOUND){
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
239 pc->buffer= av_fast_realloc(pc->buffer, &pc->buffer_size, (*buf_size) + pc->index + FF_INPUT_BUFFER_PADDING_SIZE);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
240
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
241 memcpy(&pc->buffer[pc->index], *buf, *buf_size);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
242 pc->index += *buf_size;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
243 return -1;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
244 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
245
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
246 *buf_size=
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
247 pc->overread_index= pc->index + next;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
248
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
249 /* append to buffer */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
250 if(pc->index){
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
251 pc->buffer= av_fast_realloc(pc->buffer, &pc->buffer_size, next + pc->index + FF_INPUT_BUFFER_PADDING_SIZE);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
252
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
253 memcpy(&pc->buffer[pc->index], *buf, next + FF_INPUT_BUFFER_PADDING_SIZE );
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
254 pc->index = 0;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
255 *buf= pc->buffer;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
256 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
257
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
258 /* store overread bytes */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
259 for(;next < 0; next++){
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
260 pc->state = (pc->state<<8) | pc->buffer[pc->last_index + next];
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
261 pc->overread++;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
262 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
263
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
264 #if 0
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
265 if(pc->overread){
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
266 printf("overread %d, state:%X next:%d index:%d o_index:%d\n", pc->overread, pc->state, next, pc->index, pc->overread_index);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
267 printf("%X %X %X %X\n", (*buf)[0], (*buf)[1],(*buf)[2],(*buf)[3]);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
268 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
269 #endif
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
270
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
271 return 0;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
272 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
273
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
274 static int find_start_code(const uint8_t **pbuf_ptr, const uint8_t *buf_end)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
275 {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
276 const uint8_t *buf_ptr;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
277 unsigned int state=0xFFFFFFFF, v;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
278 int val;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
279
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
280 buf_ptr = *pbuf_ptr;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
281 while (buf_ptr < buf_end) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
282 v = *buf_ptr++;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
283 if (state == 0x000001) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
284 state = ((state << 8) | v) & 0xffffff;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
285 val = state;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
286 goto found;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
287 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
288 state = ((state << 8) | v) & 0xffffff;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
289 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
290 val = -1;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
291 found:
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
292 *pbuf_ptr = buf_ptr;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
293 return val;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
294 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
295
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
296 /* XXX: merge with libavcodec ? */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
297 #define MPEG1_FRAME_RATE_BASE 1001
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
298
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
299 static const int frame_rate_tab[16] = {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
300 0,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
301 24000,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
302 24024,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
303 25025,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
304 30000,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
305 30030,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
306 50050,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
307 60000,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
308 60060,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
309 // Xing's 15fps: (9)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
310 15015,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
311 // libmpeg3's "Unofficial economy rates": (10-13)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
312 5005,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
313 10010,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
314 12012,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
315 15015,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
316 // random, just to avoid segfault !never encode these
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
317 25025,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
318 25025,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
319 };
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
320
2637
ef44d24680d1 switch to native time bases
michael
parents: 2565
diff changeset
321 //FIXME move into mpeg12.c
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
322 static void mpegvideo_extract_headers(AVCodecParserContext *s,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
323 AVCodecContext *avctx,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
324 const uint8_t *buf, int buf_size)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
325 {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
326 ParseContext1 *pc = s->priv_data;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
327 const uint8_t *buf_end;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
328 int32_t start_code;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
329 int frame_rate_index, ext_type, bytes_left;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
330 int frame_rate_ext_n, frame_rate_ext_d;
2119
f8948ed6553a field pic timestamp fix
michael
parents: 2107
diff changeset
331 int picture_structure, top_field_first, repeat_first_field, progressive_frame;
2539
1fefaaee0fdc mpeg-es bitrate parsing
michael
parents: 2522
diff changeset
332 int horiz_size_ext, vert_size_ext, bit_rate_ext;
2769
1394b45a7bf4 support changing in bitstream global headers into extradata style and back
michael
parents: 2637
diff changeset
333 //FIXME replace the crap with get_bits()
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
334 s->repeat_pict = 0;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
335 buf_end = buf + buf_size;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
336 while (buf < buf_end) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
337 start_code = find_start_code(&buf, buf_end);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
338 bytes_left = buf_end - buf;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
339 switch(start_code) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
340 case PICTURE_START_CODE:
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
341 if (bytes_left >= 2) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
342 s->pict_type = (buf[1] >> 3) & 7;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
343 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
344 break;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
345 case SEQ_START_CODE:
2539
1fefaaee0fdc mpeg-es bitrate parsing
michael
parents: 2522
diff changeset
346 if (bytes_left >= 7) {
2269
535b7dfee202 lowres fixes for the parser
michael
parents: 2120
diff changeset
347 pc->width = (buf[0] << 4) | (buf[1] >> 4);
535b7dfee202 lowres fixes for the parser
michael
parents: 2120
diff changeset
348 pc->height = ((buf[1] & 0x0f) << 8) | buf[2];
2270
21f450be6cb5 lowres width/height cleanup 3rd try
michael
parents: 2269
diff changeset
349 avcodec_set_dimensions(avctx, pc->width, pc->height);
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
350 frame_rate_index = buf[3] & 0xf;
2637
ef44d24680d1 switch to native time bases
michael
parents: 2565
diff changeset
351 pc->frame_rate = avctx->time_base.den = frame_rate_tab[frame_rate_index];
ef44d24680d1 switch to native time bases
michael
parents: 2565
diff changeset
352 avctx->time_base.num = MPEG1_FRAME_RATE_BASE;
2539
1fefaaee0fdc mpeg-es bitrate parsing
michael
parents: 2522
diff changeset
353 avctx->bit_rate = ((buf[4]<<10) | (buf[5]<<2) | (buf[6]>>6))*400;
1681
27a272442d6b fill codec info
bellard
parents: 1614
diff changeset
354 avctx->codec_id = CODEC_ID_MPEG1VIDEO;
27a272442d6b fill codec info
bellard
parents: 1614
diff changeset
355 avctx->sub_id = 1;
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
356 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
357 break;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
358 case EXT_START_CODE:
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
359 if (bytes_left >= 1) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
360 ext_type = (buf[0] >> 4);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
361 switch(ext_type) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
362 case 0x1: /* sequence extension */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
363 if (bytes_left >= 6) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
364 horiz_size_ext = ((buf[1] & 1) << 1) | (buf[2] >> 7);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
365 vert_size_ext = (buf[2] >> 5) & 3;
2539
1fefaaee0fdc mpeg-es bitrate parsing
michael
parents: 2522
diff changeset
366 bit_rate_ext = ((buf[2] & 0x1F)<<7) | (buf[3]>>1);
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
367 frame_rate_ext_n = (buf[5] >> 5) & 3;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
368 frame_rate_ext_d = (buf[5] & 0x1f);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
369 pc->progressive_sequence = buf[1] & (1 << 3);
2565
e7f2b8fadfb0 10l typo
michael
parents: 2539
diff changeset
370 avctx->has_b_frames= !(buf[5] >> 7);
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
371
2269
535b7dfee202 lowres fixes for the parser
michael
parents: 2120
diff changeset
372 pc->width |=(horiz_size_ext << 12);
535b7dfee202 lowres fixes for the parser
michael
parents: 2120
diff changeset
373 pc->height |=( vert_size_ext << 12);
2539
1fefaaee0fdc mpeg-es bitrate parsing
michael
parents: 2522
diff changeset
374 avctx->bit_rate += (bit_rate_ext << 18) * 400;
2270
21f450be6cb5 lowres width/height cleanup 3rd try
michael
parents: 2269
diff changeset
375 avcodec_set_dimensions(avctx, pc->width, pc->height);
2637
ef44d24680d1 switch to native time bases
michael
parents: 2565
diff changeset
376 avctx->time_base.den = pc->frame_rate * (frame_rate_ext_n + 1);
ef44d24680d1 switch to native time bases
michael
parents: 2565
diff changeset
377 avctx->time_base.num = MPEG1_FRAME_RATE_BASE * (frame_rate_ext_d + 1);
1681
27a272442d6b fill codec info
bellard
parents: 1614
diff changeset
378 avctx->codec_id = CODEC_ID_MPEG2VIDEO;
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
379 avctx->sub_id = 2; /* forces MPEG2 */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
380 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
381 break;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
382 case 0x8: /* picture coding extension */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
383 if (bytes_left >= 5) {
2120
872ac88d4e60 1000000l
michael
parents: 2119
diff changeset
384 picture_structure = buf[2]&3;
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
385 top_field_first = buf[3] & (1 << 7);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
386 repeat_first_field = buf[3] & (1 << 1);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
387 progressive_frame = buf[4] & (1 << 7);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
388
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
389 /* check if we must repeat the frame */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
390 if (repeat_first_field) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
391 if (pc->progressive_sequence) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
392 if (top_field_first)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
393 s->repeat_pict = 4;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
394 else
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
395 s->repeat_pict = 2;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
396 } else if (progressive_frame) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
397 s->repeat_pict = 1;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
398 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
399 }
2119
f8948ed6553a field pic timestamp fix
michael
parents: 2107
diff changeset
400
f8948ed6553a field pic timestamp fix
michael
parents: 2107
diff changeset
401 /* the packet only represents half a frame
f8948ed6553a field pic timestamp fix
michael
parents: 2107
diff changeset
402 XXX,FIXME maybe find a different solution */
f8948ed6553a field pic timestamp fix
michael
parents: 2107
diff changeset
403 if(picture_structure != 3)
f8948ed6553a field pic timestamp fix
michael
parents: 2107
diff changeset
404 s->repeat_pict = -1;
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
405 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
406 break;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
407 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
408 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
409 break;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
410 case -1:
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
411 goto the_end;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
412 default:
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
413 /* we stop parsing when we encounter a slice. It ensures
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
414 that this function takes a negligible amount of time */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
415 if (start_code >= SLICE_MIN_START_CODE &&
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
416 start_code <= SLICE_MAX_START_CODE)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
417 goto the_end;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
418 break;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
419 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
420 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
421 the_end: ;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
422 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
423
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
424 static int mpegvideo_parse(AVCodecParserContext *s,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
425 AVCodecContext *avctx,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
426 uint8_t **poutbuf, int *poutbuf_size,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
427 const uint8_t *buf, int buf_size)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
428 {
1988
b5753525f9a8 remove duplicated find_frame_end() code
michael
parents: 1987
diff changeset
429 ParseContext1 *pc1 = s->priv_data;
b5753525f9a8 remove duplicated find_frame_end() code
michael
parents: 1987
diff changeset
430 ParseContext *pc= &pc1->pc;
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
431 int next;
2837
45ccf6842c34 parse pict_type for streams in avi
michael
parents: 2777
diff changeset
432
45ccf6842c34 parse pict_type for streams in avi
michael
parents: 2777
diff changeset
433 if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){
45ccf6842c34 parse pict_type for streams in avi
michael
parents: 2777
diff changeset
434 next= buf_size;
45ccf6842c34 parse pict_type for streams in avi
michael
parents: 2777
diff changeset
435 }else{
45ccf6842c34 parse pict_type for streams in avi
michael
parents: 2777
diff changeset
436 next= ff_mpeg1_find_frame_end(pc, buf, buf_size);
45ccf6842c34 parse pict_type for streams in avi
michael
parents: 2777
diff changeset
437
45ccf6842c34 parse pict_type for streams in avi
michael
parents: 2777
diff changeset
438 if (ff_combine_frame(pc, next, (uint8_t **)&buf, &buf_size) < 0) {
45ccf6842c34 parse pict_type for streams in avi
michael
parents: 2777
diff changeset
439 *poutbuf = NULL;
45ccf6842c34 parse pict_type for streams in avi
michael
parents: 2777
diff changeset
440 *poutbuf_size = 0;
45ccf6842c34 parse pict_type for streams in avi
michael
parents: 2777
diff changeset
441 return buf_size;
45ccf6842c34 parse pict_type for streams in avi
michael
parents: 2777
diff changeset
442 }
45ccf6842c34 parse pict_type for streams in avi
michael
parents: 2777
diff changeset
443
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
444 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
445 /* we have a full frame : we just parse the first few MPEG headers
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
446 to have the full timing information. The time take by this
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
447 function should be negligible for uncorrupted streams */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
448 mpegvideo_extract_headers(s, avctx, buf, buf_size);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
449 #if 0
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
450 printf("pict_type=%d frame_rate=%0.3f repeat_pict=%d\n",
2637
ef44d24680d1 switch to native time bases
michael
parents: 2565
diff changeset
451 s->pict_type, (double)avctx->time_base.den / avctx->time_base.num, s->repeat_pict);
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
452 #endif
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
453
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
454 *poutbuf = (uint8_t *)buf;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
455 *poutbuf_size = buf_size;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
456 return next;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
457 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
458
2769
1394b45a7bf4 support changing in bitstream global headers into extradata style and back
michael
parents: 2637
diff changeset
459 static int mpegvideo_split(AVCodecContext *avctx,
1394b45a7bf4 support changing in bitstream global headers into extradata style and back
michael
parents: 2637
diff changeset
460 const uint8_t *buf, int buf_size)
1394b45a7bf4 support changing in bitstream global headers into extradata style and back
michael
parents: 2637
diff changeset
461 {
1394b45a7bf4 support changing in bitstream global headers into extradata style and back
michael
parents: 2637
diff changeset
462 int i;
1394b45a7bf4 support changing in bitstream global headers into extradata style and back
michael
parents: 2637
diff changeset
463 uint32_t state= -1;
1394b45a7bf4 support changing in bitstream global headers into extradata style and back
michael
parents: 2637
diff changeset
464
1394b45a7bf4 support changing in bitstream global headers into extradata style and back
michael
parents: 2637
diff changeset
465 for(i=0; i<buf_size; i++){
1394b45a7bf4 support changing in bitstream global headers into extradata style and back
michael
parents: 2637
diff changeset
466 state= (state<<8) | buf[i];
1394b45a7bf4 support changing in bitstream global headers into extradata style and back
michael
parents: 2637
diff changeset
467 if(state != 0x1B3 && state != 0x1B5 && state < 0x200 && state >= 0x100)
2777
09108466b7d0 off by 1 error bugfix
michael
parents: 2769
diff changeset
468 return i-3;
2769
1394b45a7bf4 support changing in bitstream global headers into extradata style and back
michael
parents: 2637
diff changeset
469 }
1394b45a7bf4 support changing in bitstream global headers into extradata style and back
michael
parents: 2637
diff changeset
470 return 0;
1394b45a7bf4 support changing in bitstream global headers into extradata style and back
michael
parents: 2637
diff changeset
471 }
1394b45a7bf4 support changing in bitstream global headers into extradata style and back
michael
parents: 2637
diff changeset
472
1988
b5753525f9a8 remove duplicated find_frame_end() code
michael
parents: 1987
diff changeset
473 void ff_parse_close(AVCodecParserContext *s)
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
474 {
1988
b5753525f9a8 remove duplicated find_frame_end() code
michael
parents: 1987
diff changeset
475 ParseContext *pc = s->priv_data;
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
476
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
477 av_free(pc->buffer);
1988
b5753525f9a8 remove duplicated find_frame_end() code
michael
parents: 1987
diff changeset
478 }
b5753525f9a8 remove duplicated find_frame_end() code
michael
parents: 1987
diff changeset
479
b5753525f9a8 remove duplicated find_frame_end() code
michael
parents: 1987
diff changeset
480 static void parse1_close(AVCodecParserContext *s)
b5753525f9a8 remove duplicated find_frame_end() code
michael
parents: 1987
diff changeset
481 {
b5753525f9a8 remove duplicated find_frame_end() code
michael
parents: 1987
diff changeset
482 ParseContext1 *pc1 = s->priv_data;
b5753525f9a8 remove duplicated find_frame_end() code
michael
parents: 1987
diff changeset
483
b5753525f9a8 remove duplicated find_frame_end() code
michael
parents: 1987
diff changeset
484 av_free(pc1->pc.buffer);
b5753525f9a8 remove duplicated find_frame_end() code
michael
parents: 1987
diff changeset
485 av_free(pc1->enc);
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
486 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
487
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
488 /*************************/
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
489
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
490 /* used by parser */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
491 /* XXX: make it use less memory */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
492 static int av_mpeg4_decode_header(AVCodecParserContext *s1,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
493 AVCodecContext *avctx,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
494 const uint8_t *buf, int buf_size)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
495 {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
496 ParseContext1 *pc = s1->priv_data;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
497 MpegEncContext *s = pc->enc;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
498 GetBitContext gb1, *gb = &gb1;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
499 int ret;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
500
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
501 s->avctx = avctx;
1614
6c82ef97d3e6 also parse extradata for MPEG4
bellard
parents: 1613
diff changeset
502 s->current_picture_ptr = &s->current_picture;
6c82ef97d3e6 also parse extradata for MPEG4
bellard
parents: 1613
diff changeset
503
6c82ef97d3e6 also parse extradata for MPEG4
bellard
parents: 1613
diff changeset
504 if (avctx->extradata_size && pc->first_picture){
6c82ef97d3e6 also parse extradata for MPEG4
bellard
parents: 1613
diff changeset
505 init_get_bits(gb, avctx->extradata, avctx->extradata_size*8);
6c82ef97d3e6 also parse extradata for MPEG4
bellard
parents: 1613
diff changeset
506 ret = ff_mpeg4_decode_picture_header(s, gb);
6c82ef97d3e6 also parse extradata for MPEG4
bellard
parents: 1613
diff changeset
507 }
6c82ef97d3e6 also parse extradata for MPEG4
bellard
parents: 1613
diff changeset
508
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
509 init_get_bits(gb, buf, 8 * buf_size);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
510 ret = ff_mpeg4_decode_picture_header(s, gb);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
511 if (s->width) {
2270
21f450be6cb5 lowres width/height cleanup 3rd try
michael
parents: 2269
diff changeset
512 avcodec_set_dimensions(avctx, s->width, s->height);
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
513 }
2837
45ccf6842c34 parse pict_type for streams in avi
michael
parents: 2777
diff changeset
514 s1->pict_type= s->pict_type;
1614
6c82ef97d3e6 also parse extradata for MPEG4
bellard
parents: 1613
diff changeset
515 pc->first_picture = 0;
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
516 return ret;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
517 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
518
2024
f65d87bfdd5a some of the warning fixes by (Michael Roitzsch <mroi at users dot sourceforge dot net>)
michael
parents: 1988
diff changeset
519 static int mpeg4video_parse_init(AVCodecParserContext *s)
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
520 {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
521 ParseContext1 *pc = s->priv_data;
1614
6c82ef97d3e6 also parse extradata for MPEG4
bellard
parents: 1613
diff changeset
522
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
523 pc->enc = av_mallocz(sizeof(MpegEncContext));
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
524 if (!pc->enc)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
525 return -1;
1614
6c82ef97d3e6 also parse extradata for MPEG4
bellard
parents: 1613
diff changeset
526 pc->first_picture = 1;
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
527 return 0;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
528 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
529
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
530 static int mpeg4video_parse(AVCodecParserContext *s,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
531 AVCodecContext *avctx,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
532 uint8_t **poutbuf, int *poutbuf_size,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
533 const uint8_t *buf, int buf_size)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
534 {
1988
b5753525f9a8 remove duplicated find_frame_end() code
michael
parents: 1987
diff changeset
535 ParseContext *pc = s->priv_data;
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
536 int next;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
537
2837
45ccf6842c34 parse pict_type for streams in avi
michael
parents: 2777
diff changeset
538 if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){
45ccf6842c34 parse pict_type for streams in avi
michael
parents: 2777
diff changeset
539 next= buf_size;
45ccf6842c34 parse pict_type for streams in avi
michael
parents: 2777
diff changeset
540 }else{
45ccf6842c34 parse pict_type for streams in avi
michael
parents: 2777
diff changeset
541 next= ff_mpeg4_find_frame_end(pc, buf, buf_size);
45ccf6842c34 parse pict_type for streams in avi
michael
parents: 2777
diff changeset
542
45ccf6842c34 parse pict_type for streams in avi
michael
parents: 2777
diff changeset
543 if (ff_combine_frame(pc, next, (uint8_t **)&buf, &buf_size) < 0) {
45ccf6842c34 parse pict_type for streams in avi
michael
parents: 2777
diff changeset
544 *poutbuf = NULL;
45ccf6842c34 parse pict_type for streams in avi
michael
parents: 2777
diff changeset
545 *poutbuf_size = 0;
45ccf6842c34 parse pict_type for streams in avi
michael
parents: 2777
diff changeset
546 return buf_size;
45ccf6842c34 parse pict_type for streams in avi
michael
parents: 2777
diff changeset
547 }
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
548 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
549 av_mpeg4_decode_header(s, avctx, buf, buf_size);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
550
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
551 *poutbuf = (uint8_t *)buf;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
552 *poutbuf_size = buf_size;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
553 return next;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
554 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
555
2769
1394b45a7bf4 support changing in bitstream global headers into extradata style and back
michael
parents: 2637
diff changeset
556 static int mpeg4video_split(AVCodecContext *avctx,
1394b45a7bf4 support changing in bitstream global headers into extradata style and back
michael
parents: 2637
diff changeset
557 const uint8_t *buf, int buf_size)
1394b45a7bf4 support changing in bitstream global headers into extradata style and back
michael
parents: 2637
diff changeset
558 {
1394b45a7bf4 support changing in bitstream global headers into extradata style and back
michael
parents: 2637
diff changeset
559 int i;
1394b45a7bf4 support changing in bitstream global headers into extradata style and back
michael
parents: 2637
diff changeset
560 uint32_t state= -1;
1394b45a7bf4 support changing in bitstream global headers into extradata style and back
michael
parents: 2637
diff changeset
561
1394b45a7bf4 support changing in bitstream global headers into extradata style and back
michael
parents: 2637
diff changeset
562 for(i=0; i<buf_size; i++){
1394b45a7bf4 support changing in bitstream global headers into extradata style and back
michael
parents: 2637
diff changeset
563 state= (state<<8) | buf[i];
1394b45a7bf4 support changing in bitstream global headers into extradata style and back
michael
parents: 2637
diff changeset
564 if(state == 0x1B3 || state == 0x1B6)
2777
09108466b7d0 off by 1 error bugfix
michael
parents: 2769
diff changeset
565 return i-3;
2769
1394b45a7bf4 support changing in bitstream global headers into extradata style and back
michael
parents: 2637
diff changeset
566 }
1394b45a7bf4 support changing in bitstream global headers into extradata style and back
michael
parents: 2637
diff changeset
567 return 0;
1394b45a7bf4 support changing in bitstream global headers into extradata style and back
michael
parents: 2637
diff changeset
568 }
1394b45a7bf4 support changing in bitstream global headers into extradata style and back
michael
parents: 2637
diff changeset
569
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
570 /*************************/
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
571
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
572 typedef struct MpegAudioParseContext {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
573 uint8_t inbuf[MPA_MAX_CODED_FRAME_SIZE]; /* input buffer */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
574 uint8_t *inbuf_ptr;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
575 int frame_size;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
576 int free_format_frame_size;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
577 int free_format_next_header;
2470
06aafb585f69 require a few valid and equal mp3 headers for resync
michael
parents: 2389
diff changeset
578 uint32_t header;
06aafb585f69 require a few valid and equal mp3 headers for resync
michael
parents: 2389
diff changeset
579 int header_count;
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
580 } MpegAudioParseContext;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
581
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
582 #define MPA_HEADER_SIZE 4
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
583
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
584 /* header + layer + bitrate + freq + lsf/mpeg25 */
2522
e25782262d7d kill warnings patch by (M?ns Rullg?rd <mru inprovide com>)
michael
parents: 2486
diff changeset
585 #undef SAME_HEADER_MASK /* mpegaudio.h defines different version */
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
586 #define SAME_HEADER_MASK \
2480
5252700f61df 10000l vbr mp3 fix
michael
parents: 2470
diff changeset
587 (0xffe00000 | (3 << 17) | (3 << 10) | (3 << 19))
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
588
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
589 static int mpegaudio_parse_init(AVCodecParserContext *s1)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
590 {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
591 MpegAudioParseContext *s = s1->priv_data;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
592 s->inbuf_ptr = s->inbuf;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
593 return 0;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
594 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
595
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
596 static int mpegaudio_parse(AVCodecParserContext *s1,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
597 AVCodecContext *avctx,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
598 uint8_t **poutbuf, int *poutbuf_size,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
599 const uint8_t *buf, int buf_size)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
600 {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
601 MpegAudioParseContext *s = s1->priv_data;
2470
06aafb585f69 require a few valid and equal mp3 headers for resync
michael
parents: 2389
diff changeset
602 int len, ret, sr;
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
603 uint32_t header;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
604 const uint8_t *buf_ptr;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
605
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
606 *poutbuf = NULL;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
607 *poutbuf_size = 0;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
608 buf_ptr = buf;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
609 while (buf_size > 0) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
610 len = s->inbuf_ptr - s->inbuf;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
611 if (s->frame_size == 0) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
612 /* special case for next header for first frame in free
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
613 format case (XXX: find a simpler method) */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
614 if (s->free_format_next_header != 0) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
615 s->inbuf[0] = s->free_format_next_header >> 24;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
616 s->inbuf[1] = s->free_format_next_header >> 16;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
617 s->inbuf[2] = s->free_format_next_header >> 8;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
618 s->inbuf[3] = s->free_format_next_header;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
619 s->inbuf_ptr = s->inbuf + 4;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
620 s->free_format_next_header = 0;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
621 goto got_header;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
622 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
623 /* no header seen : find one. We need at least MPA_HEADER_SIZE
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
624 bytes to parse it */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
625 len = MPA_HEADER_SIZE - len;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
626 if (len > buf_size)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
627 len = buf_size;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
628 if (len > 0) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
629 memcpy(s->inbuf_ptr, buf_ptr, len);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
630 buf_ptr += len;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
631 buf_size -= len;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
632 s->inbuf_ptr += len;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
633 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
634 if ((s->inbuf_ptr - s->inbuf) >= MPA_HEADER_SIZE) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
635 got_header:
2470
06aafb585f69 require a few valid and equal mp3 headers for resync
michael
parents: 2389
diff changeset
636 sr= avctx->sample_rate;
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
637 header = (s->inbuf[0] << 24) | (s->inbuf[1] << 16) |
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
638 (s->inbuf[2] << 8) | s->inbuf[3];
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
639
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
640 ret = mpa_decode_header(avctx, header);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
641 if (ret < 0) {
2470
06aafb585f69 require a few valid and equal mp3 headers for resync
michael
parents: 2389
diff changeset
642 s->header_count= -2;
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
643 /* no sync found : move by one byte (inefficient, but simple!) */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
644 memmove(s->inbuf, s->inbuf + 1, s->inbuf_ptr - s->inbuf - 1);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
645 s->inbuf_ptr--;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
646 dprintf("skip %x\n", header);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
647 /* reset free format frame size to give a chance
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
648 to get a new bitrate */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
649 s->free_format_frame_size = 0;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
650 } else {
2470
06aafb585f69 require a few valid and equal mp3 headers for resync
michael
parents: 2389
diff changeset
651 if((header&SAME_HEADER_MASK) != (s->header&SAME_HEADER_MASK) && s->header)
06aafb585f69 require a few valid and equal mp3 headers for resync
michael
parents: 2389
diff changeset
652 s->header_count= -3;
06aafb585f69 require a few valid and equal mp3 headers for resync
michael
parents: 2389
diff changeset
653 s->header= header;
06aafb585f69 require a few valid and equal mp3 headers for resync
michael
parents: 2389
diff changeset
654 s->header_count++;
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
655 s->frame_size = ret;
2470
06aafb585f69 require a few valid and equal mp3 headers for resync
michael
parents: 2389
diff changeset
656
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
657 #if 0
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
658 /* free format: prepare to compute frame size */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
659 if (decode_header(s, header) == 1) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
660 s->frame_size = -1;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
661 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
662 #endif
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
663 }
2470
06aafb585f69 require a few valid and equal mp3 headers for resync
michael
parents: 2389
diff changeset
664 if(s->header_count <= 0)
06aafb585f69 require a few valid and equal mp3 headers for resync
michael
parents: 2389
diff changeset
665 avctx->sample_rate= sr; //FIXME ugly
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
666 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
667 } else
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
668 #if 0
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
669 if (s->frame_size == -1) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
670 /* free format : find next sync to compute frame size */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
671 len = MPA_MAX_CODED_FRAME_SIZE - len;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
672 if (len > buf_size)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
673 len = buf_size;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
674 if (len == 0) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
675 /* frame too long: resync */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
676 s->frame_size = 0;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
677 memmove(s->inbuf, s->inbuf + 1, s->inbuf_ptr - s->inbuf - 1);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
678 s->inbuf_ptr--;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
679 } else {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
680 uint8_t *p, *pend;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
681 uint32_t header1;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
682 int padding;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
683
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
684 memcpy(s->inbuf_ptr, buf_ptr, len);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
685 /* check for header */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
686 p = s->inbuf_ptr - 3;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
687 pend = s->inbuf_ptr + len - 4;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
688 while (p <= pend) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
689 header = (p[0] << 24) | (p[1] << 16) |
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
690 (p[2] << 8) | p[3];
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
691 header1 = (s->inbuf[0] << 24) | (s->inbuf[1] << 16) |
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
692 (s->inbuf[2] << 8) | s->inbuf[3];
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
693 /* check with high probability that we have a
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
694 valid header */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
695 if ((header & SAME_HEADER_MASK) ==
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
696 (header1 & SAME_HEADER_MASK)) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
697 /* header found: update pointers */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
698 len = (p + 4) - s->inbuf_ptr;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
699 buf_ptr += len;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
700 buf_size -= len;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
701 s->inbuf_ptr = p;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
702 /* compute frame size */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
703 s->free_format_next_header = header;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
704 s->free_format_frame_size = s->inbuf_ptr - s->inbuf;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
705 padding = (header1 >> 9) & 1;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
706 if (s->layer == 1)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
707 s->free_format_frame_size -= padding * 4;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
708 else
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
709 s->free_format_frame_size -= padding;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
710 dprintf("free frame size=%d padding=%d\n",
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
711 s->free_format_frame_size, padding);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
712 decode_header(s, header1);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
713 goto next_data;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
714 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
715 p++;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
716 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
717 /* not found: simply increase pointers */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
718 buf_ptr += len;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
719 s->inbuf_ptr += len;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
720 buf_size -= len;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
721 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
722 } else
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
723 #endif
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
724 if (len < s->frame_size) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
725 if (s->frame_size > MPA_MAX_CODED_FRAME_SIZE)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
726 s->frame_size = MPA_MAX_CODED_FRAME_SIZE;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
727 len = s->frame_size - len;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
728 if (len > buf_size)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
729 len = buf_size;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
730 memcpy(s->inbuf_ptr, buf_ptr, len);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
731 buf_ptr += len;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
732 s->inbuf_ptr += len;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
733 buf_size -= len;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
734 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
735 // next_data:
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
736 if (s->frame_size > 0 &&
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
737 (s->inbuf_ptr - s->inbuf) >= s->frame_size) {
2470
06aafb585f69 require a few valid and equal mp3 headers for resync
michael
parents: 2389
diff changeset
738 if(s->header_count > 0){
06aafb585f69 require a few valid and equal mp3 headers for resync
michael
parents: 2389
diff changeset
739 *poutbuf = s->inbuf;
06aafb585f69 require a few valid and equal mp3 headers for resync
michael
parents: 2389
diff changeset
740 *poutbuf_size = s->inbuf_ptr - s->inbuf;
06aafb585f69 require a few valid and equal mp3 headers for resync
michael
parents: 2389
diff changeset
741 }
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
742 s->inbuf_ptr = s->inbuf;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
743 s->frame_size = 0;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
744 break;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
745 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
746 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
747 return buf_ptr - buf;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
748 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
749
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
750 #ifdef CONFIG_AC3
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
751 extern int a52_syncinfo (const uint8_t * buf, int * flags,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
752 int * sample_rate, int * bit_rate);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
753
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
754 typedef struct AC3ParseContext {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
755 uint8_t inbuf[4096]; /* input buffer */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
756 uint8_t *inbuf_ptr;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
757 int frame_size;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
758 int flags;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
759 } AC3ParseContext;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
760
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
761 #define AC3_HEADER_SIZE 7
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
762 #define A52_LFE 16
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
763
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
764 static int ac3_parse_init(AVCodecParserContext *s1)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
765 {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
766 AC3ParseContext *s = s1->priv_data;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
767 s->inbuf_ptr = s->inbuf;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
768 return 0;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
769 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
770
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
771 static int ac3_parse(AVCodecParserContext *s1,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
772 AVCodecContext *avctx,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
773 uint8_t **poutbuf, int *poutbuf_size,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
774 const uint8_t *buf, int buf_size)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
775 {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
776 AC3ParseContext *s = s1->priv_data;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
777 const uint8_t *buf_ptr;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
778 int len, sample_rate, bit_rate;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
779 static const int ac3_channels[8] = {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
780 2, 1, 2, 3, 3, 4, 4, 5
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
781 };
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
782
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
783 *poutbuf = NULL;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
784 *poutbuf_size = 0;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
785
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
786 buf_ptr = buf;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
787 while (buf_size > 0) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
788 len = s->inbuf_ptr - s->inbuf;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
789 if (s->frame_size == 0) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
790 /* no header seen : find one. We need at least 7 bytes to parse it */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
791 len = AC3_HEADER_SIZE - len;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
792 if (len > buf_size)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
793 len = buf_size;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
794 memcpy(s->inbuf_ptr, buf_ptr, len);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
795 buf_ptr += len;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
796 s->inbuf_ptr += len;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
797 buf_size -= len;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
798 if ((s->inbuf_ptr - s->inbuf) == AC3_HEADER_SIZE) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
799 len = a52_syncinfo(s->inbuf, &s->flags, &sample_rate, &bit_rate);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
800 if (len == 0) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
801 /* no sync found : move by one byte (inefficient, but simple!) */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
802 memmove(s->inbuf, s->inbuf + 1, AC3_HEADER_SIZE - 1);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
803 s->inbuf_ptr--;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
804 } else {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
805 s->frame_size = len;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
806 /* update codec info */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
807 avctx->sample_rate = sample_rate;
1987
d9e067853051 >2 channels decoding fix
michael
parents: 1696
diff changeset
808 /* set channels,except if the user explicitly requests 1 or 2 channels, XXX/FIXME this is a bit ugly */
d9e067853051 >2 channels decoding fix
michael
parents: 1696
diff changeset
809 if(avctx->channels!=1 && avctx->channels!=2){
d9e067853051 >2 channels decoding fix
michael
parents: 1696
diff changeset
810 avctx->channels = ac3_channels[s->flags & 7];
d9e067853051 >2 channels decoding fix
michael
parents: 1696
diff changeset
811 if (s->flags & A52_LFE)
d9e067853051 >2 channels decoding fix
michael
parents: 1696
diff changeset
812 avctx->channels++;
d9e067853051 >2 channels decoding fix
michael
parents: 1696
diff changeset
813 }
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
814 avctx->bit_rate = bit_rate;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
815 avctx->frame_size = 6 * 256;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
816 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
817 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
818 } else if (len < s->frame_size) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
819 len = s->frame_size - len;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
820 if (len > buf_size)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
821 len = buf_size;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
822
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
823 memcpy(s->inbuf_ptr, buf_ptr, len);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
824 buf_ptr += len;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
825 s->inbuf_ptr += len;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
826 buf_size -= len;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
827 } else {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
828 *poutbuf = s->inbuf;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
829 *poutbuf_size = s->frame_size;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
830 s->inbuf_ptr = s->inbuf;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
831 s->frame_size = 0;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
832 break;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
833 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
834 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
835 return buf_ptr - buf;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
836 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
837 #endif
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
838
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
839 AVCodecParser mpegvideo_parser = {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
840 { CODEC_ID_MPEG1VIDEO, CODEC_ID_MPEG2VIDEO },
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
841 sizeof(ParseContext1),
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
842 NULL,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
843 mpegvideo_parse,
1988
b5753525f9a8 remove duplicated find_frame_end() code
michael
parents: 1987
diff changeset
844 parse1_close,
2769
1394b45a7bf4 support changing in bitstream global headers into extradata style and back
michael
parents: 2637
diff changeset
845 mpegvideo_split,
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
846 };
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
847
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
848 AVCodecParser mpeg4video_parser = {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
849 { CODEC_ID_MPEG4 },
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
850 sizeof(ParseContext1),
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
851 mpeg4video_parse_init,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
852 mpeg4video_parse,
1988
b5753525f9a8 remove duplicated find_frame_end() code
michael
parents: 1987
diff changeset
853 parse1_close,
2769
1394b45a7bf4 support changing in bitstream global headers into extradata style and back
michael
parents: 2637
diff changeset
854 mpeg4video_split,
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
855 };
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
856
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
857 AVCodecParser mpegaudio_parser = {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
858 { CODEC_ID_MP2, CODEC_ID_MP3 },
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
859 sizeof(MpegAudioParseContext),
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
860 mpegaudio_parse_init,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
861 mpegaudio_parse,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
862 NULL,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
863 };
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
864
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
865 #ifdef CONFIG_AC3
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
866 AVCodecParser ac3_parser = {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
867 { CODEC_ID_AC3 },
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
868 sizeof(AC3ParseContext),
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
869 ac3_parse_init,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
870 ac3_parse,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
871 NULL,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
872 };
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
873 #endif