AVCodecParserContext *s;
AVCodecParser *parser;
int ret;
+
+ if(codec_id == CODEC_ID_NONE)
+ return NULL;
for(parser = av_first_parser; parser != NULL; parser = parser->next) {
if (parser->codec_ids[0] == codec_id ||
parser->codec_ids[1] == codec_id ||
- parser->codec_ids[2] == codec_id)
+ parser->codec_ids[2] == codec_id ||
+ parser->codec_ids[3] == codec_id ||
+ parser->codec_ids[4] == codec_id)
goto found;
}
return NULL;
return index;
}
+/**
+ *
+ * @return 0 if the output buffer is a subset of the input, 1 if it is allocated and must be freed
+ */
+int av_parser_change(AVCodecParserContext *s,
+ AVCodecContext *avctx,
+ uint8_t **poutbuf, int *poutbuf_size,
+ const uint8_t *buf, int buf_size, int keyframe){
+
+ if(s && s->parser->split){
+ if((avctx->flags & CODEC_FLAG_GLOBAL_HEADER) || (avctx->flags2 & CODEC_FLAG2_LOCAL_HEADER)){
+ int i= s->parser->split(avctx, buf, buf_size);
+ buf += i;
+ buf_size -= i;
+ }
+ }
+
+ *poutbuf= buf;
+ *poutbuf_size= buf_size;
+ if(avctx->extradata){
+ if( (keyframe && (avctx->flags2 & CODEC_FLAG2_LOCAL_HEADER))
+ /*||(s->pict_type != I_TYPE && (s->flags & PARSER_FLAG_DUMP_EXTRADATA_AT_NOKEY))*/
+ /*||(? && (s->flags & PARSER_FLAG_DUMP_EXTRADATA_AT_BEGIN)*/){
+ int size= buf_size + avctx->extradata_size;
+ *poutbuf_size= size;
+ *poutbuf= av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE);
+
+ memcpy(*poutbuf, avctx->extradata, avctx->extradata_size);
+ memcpy((*poutbuf) + avctx->extradata_size, buf, buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
void av_parser_close(AVCodecParserContext *s)
{
if (s->parser->parser_close)
for(; pc->overread>0; pc->overread--){
pc->buffer[pc->index++]= pc->buffer[pc->overread_index++];
}
-
+
+ /* flush remaining if EOF */
+ if(!*buf_size && next == END_NOT_FOUND){
+ next= 0;
+ }
+
pc->last_index= pc->index;
/* copy into buffer end return */
25025,
};
+//FIXME move into mpeg12.c
static void mpegvideo_extract_headers(AVCodecParserContext *s,
AVCodecContext *avctx,
const uint8_t *buf, int buf_size)
int frame_rate_index, ext_type, bytes_left;
int frame_rate_ext_n, frame_rate_ext_d;
int picture_structure, top_field_first, repeat_first_field, progressive_frame;
- int horiz_size_ext, vert_size_ext;
-
+ int horiz_size_ext, vert_size_ext, bit_rate_ext;
+//FIXME replace the crap with get_bits()
s->repeat_pict = 0;
buf_end = buf + buf_size;
while (buf < buf_end) {
}
break;
case SEQ_START_CODE:
- if (bytes_left >= 4) {
+ if (bytes_left >= 7) {
pc->width = (buf[0] << 4) | (buf[1] >> 4);
pc->height = ((buf[1] & 0x0f) << 8) | buf[2];
- avctx->width = -((-pc->width )>>avctx->lowres);
- avctx->height = -((-pc->height)>>avctx->lowres);
+ avcodec_set_dimensions(avctx, pc->width, pc->height);
frame_rate_index = buf[3] & 0xf;
- pc->frame_rate = avctx->frame_rate = frame_rate_tab[frame_rate_index];
- avctx->frame_rate_base = MPEG1_FRAME_RATE_BASE;
+ pc->frame_rate = avctx->time_base.den = frame_rate_tab[frame_rate_index];
+ avctx->time_base.num = MPEG1_FRAME_RATE_BASE;
+ avctx->bit_rate = ((buf[4]<<10) | (buf[5]<<2) | (buf[6]>>6))*400;
avctx->codec_id = CODEC_ID_MPEG1VIDEO;
avctx->sub_id = 1;
}
if (bytes_left >= 6) {
horiz_size_ext = ((buf[1] & 1) << 1) | (buf[2] >> 7);
vert_size_ext = (buf[2] >> 5) & 3;
+ bit_rate_ext = ((buf[2] & 0x1F)<<7) | (buf[3]>>1);
frame_rate_ext_n = (buf[5] >> 5) & 3;
frame_rate_ext_d = (buf[5] & 0x1f);
pc->progressive_sequence = buf[1] & (1 << 3);
+ avctx->has_b_frames= !(buf[5] >> 7);
pc->width |=(horiz_size_ext << 12);
pc->height |=( vert_size_ext << 12);
- avctx->width = -((-pc->width )>>avctx->lowres);
- avctx->height = -((-pc->height)>>avctx->lowres);
- avctx->frame_rate = pc->frame_rate * (frame_rate_ext_n + 1);
- avctx->frame_rate_base = MPEG1_FRAME_RATE_BASE * (frame_rate_ext_d + 1);
+ avctx->bit_rate += (bit_rate_ext << 18) * 400;
+ avcodec_set_dimensions(avctx, pc->width, pc->height);
+ avctx->time_base.den = pc->frame_rate * (frame_rate_ext_n + 1);
+ avctx->time_base.num = MPEG1_FRAME_RATE_BASE * (frame_rate_ext_d + 1);
avctx->codec_id = CODEC_ID_MPEG2VIDEO;
avctx->sub_id = 2; /* forces MPEG2 */
}
mpegvideo_extract_headers(s, avctx, buf, buf_size);
#if 0
printf("pict_type=%d frame_rate=%0.3f repeat_pict=%d\n",
- s->pict_type, (double)avctx->frame_rate / avctx->frame_rate_base, s->repeat_pict);
+ s->pict_type, (double)avctx->time_base.den / avctx->time_base.num, s->repeat_pict);
#endif
*poutbuf = (uint8_t *)buf;
return next;
}
+static int mpegvideo_split(AVCodecContext *avctx,
+ const uint8_t *buf, int buf_size)
+{
+ int i;
+ uint32_t state= -1;
+
+ for(i=0; i<buf_size; i++){
+ state= (state<<8) | buf[i];
+ if(state != 0x1B3 && state != 0x1B5 && state < 0x200 && state >= 0x100)
+ return i-3;
+ }
+ return 0;
+}
+
void ff_parse_close(AVCodecParserContext *s)
{
ParseContext *pc = s->priv_data;
init_get_bits(gb, buf, 8 * buf_size);
ret = ff_mpeg4_decode_picture_header(s, gb);
if (s->width) {
- avctx->width = -((-s->width )>>avctx->lowres);
- avctx->height = -((-s->height)>>avctx->lowres);
+ avcodec_set_dimensions(avctx, s->width, s->height);
}
pc->first_picture = 0;
return ret;
return next;
}
+static int mpeg4video_split(AVCodecContext *avctx,
+ const uint8_t *buf, int buf_size)
+{
+ int i;
+ uint32_t state= -1;
+
+ for(i=0; i<buf_size; i++){
+ state= (state<<8) | buf[i];
+ if(state == 0x1B3 || state == 0x1B6)
+ return i-3;
+ }
+ return 0;
+}
+
/*************************/
typedef struct MpegAudioParseContext {
int frame_size;
int free_format_frame_size;
int free_format_next_header;
+ uint32_t header;
+ int header_count;
} MpegAudioParseContext;
#define MPA_HEADER_SIZE 4
/* header + layer + bitrate + freq + lsf/mpeg25 */
+#undef SAME_HEADER_MASK /* mpegaudio.h defines different version */
#define SAME_HEADER_MASK \
- (0xffe00000 | (3 << 17) | (0xf << 12) | (3 << 10) | (3 << 19))
+ (0xffe00000 | (3 << 17) | (3 << 10) | (3 << 19))
static int mpegaudio_parse_init(AVCodecParserContext *s1)
{
const uint8_t *buf, int buf_size)
{
MpegAudioParseContext *s = s1->priv_data;
- int len, ret;
+ int len, ret, sr;
uint32_t header;
const uint8_t *buf_ptr;
}
if ((s->inbuf_ptr - s->inbuf) >= MPA_HEADER_SIZE) {
got_header:
+ sr= avctx->sample_rate;
header = (s->inbuf[0] << 24) | (s->inbuf[1] << 16) |
(s->inbuf[2] << 8) | s->inbuf[3];
ret = mpa_decode_header(avctx, header);
if (ret < 0) {
+ s->header_count= -2;
/* no sync found : move by one byte (inefficient, but simple!) */
memmove(s->inbuf, s->inbuf + 1, s->inbuf_ptr - s->inbuf - 1);
s->inbuf_ptr--;
to get a new bitrate */
s->free_format_frame_size = 0;
} else {
+ if((header&SAME_HEADER_MASK) != (s->header&SAME_HEADER_MASK) && s->header)
+ s->header_count= -3;
+ s->header= header;
+ s->header_count++;
s->frame_size = ret;
+
#if 0
/* free format: prepare to compute frame size */
if (decode_header(s, header) == 1) {
}
#endif
}
+ if(s->header_count <= 0)
+ avctx->sample_rate= sr; //FIXME ugly
}
} else
#if 0
// next_data:
if (s->frame_size > 0 &&
(s->inbuf_ptr - s->inbuf) >= s->frame_size) {
- *poutbuf = s->inbuf;
- *poutbuf_size = s->inbuf_ptr - s->inbuf;
+ if(s->header_count > 0){
+ *poutbuf = s->inbuf;
+ *poutbuf_size = s->inbuf_ptr - s->inbuf;
+ }
s->inbuf_ptr = s->inbuf;
s->frame_size = 0;
break;
NULL,
mpegvideo_parse,
parse1_close,
+ mpegvideo_split,
};
AVCodecParser mpeg4video_parser = {
mpeg4video_parse_init,
mpeg4video_parse,
parse1_close,
+ mpeg4video_split,
};
AVCodecParser mpegaudio_parser = {