Commit d07f9043 authored by Michael Niedermayer's avatar Michael Niedermayer
Browse files

truncated h263 decoding support / H263-ES "demuxer"

Originally committed as revision 1898 to svn://svn.ffmpeg.org/ffmpeg/trunk
parent e67e14d5
......@@ -3902,10 +3902,21 @@ static inline int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block,
/* most is hardcoded. should extend to handle all h263 streams */
int h263_decode_picture_header(MpegEncContext *s)
{
int format, width, height;
int format, width, height, i;
uint32_t startcode;
align_get_bits(&s->gb);
/* picture start code */
if (get_bits_long(&s->gb, 22) != 0x20) {
startcode= get_bits(&s->gb, 22-8);
for(i= s->gb.size_in_bits - get_bits_count(&s->gb); i>0; i--) {
startcode = ((startcode << 8) | get_bits(&s->gb, 8)) & 0x003FFFFF;
if(startcode == 0x20)
break;
}
if (startcode != 0x20) {
fprintf(stderr, "Bad picture start code\n");
return -1;
}
......@@ -3988,15 +3999,26 @@ int h263_decode_picture_header(MpegEncContext *s)
s->h263_aic = 1;
}
skip_bits(&s->gb, 7);
/* these are the 7 bits: (in order of appearence */
/* Deblocking Filter */
/* Slice Structured */
/* Reference Picture Selection */
/* Independent Segment Decoding */
/* Alternative Inter VLC */
/* Modified Quantization */
/* Prevent start code emulation */
if (get_bits1(&s->gb) != 0) {
fprintf(stderr, "Deblocking Filter not supported\n");
}
if (get_bits1(&s->gb) != 0) {
fprintf(stderr, "Slice Structured not supported\n");
}
if (get_bits1(&s->gb) != 0) {
fprintf(stderr, "Reference Picture Selection not supported\n");
}
if (get_bits1(&s->gb) != 0) {
fprintf(stderr, "Independent Segment Decoding not supported\n");
}
if (get_bits1(&s->gb) != 0) {
fprintf(stderr, "Alternative Inter VLC not supported\n");
}
if (get_bits1(&s->gb) != 0) {
fprintf(stderr, "Modified Quantization not supported\n");
}
skip_bits(&s->gb, 1); /* Prevent start code emulation */
skip_bits(&s->gb, 3); /* Reserved */
} else if (ufep != 0) {
......@@ -4072,6 +4094,18 @@ int h263_decode_picture_header(MpegEncContext *s)
s->c_dc_scale_table= ff_mpeg1_dc_scale_table;
}
if(s->avctx->debug&FF_DEBUG_PICT_INFO){
printf("qp:%d %c size:%d rnd:%d %s %s %s %s\n",
s->qscale, av_get_pict_type_char(s->pict_type),
s->gb.size_in_bits, 1-s->no_rounding,
s->mv_type == MV_TYPE_8X8 ? "ADV" : "",
s->umvplus ? "UMV" : "",
s->h263_long_vectors ? "LONG" : "",
s->h263_plus ? "+" : ""
);
}
return 0;
}
......
......@@ -341,6 +341,42 @@ static int mpeg4_find_frame_end(MpegEncContext *s, uint8_t *buf, int buf_size){
return END_NOT_FOUND;
}
static int h263_find_frame_end(MpegEncContext *s, uint8_t *buf, int buf_size){
ParseContext *pc= &s->parse_context;
int vop_found, i;
uint32_t state;
vop_found= pc->frame_start_found;
state= pc->state;
i=0;
if(!vop_found){
for(i=0; i<buf_size; i++){
state= (state<<8) | buf[i];
if(state>>(32-22) == 0x20){
i++;
vop_found=1;
break;
}
}
}
if(vop_found){
for(; i<buf_size; i++){
state= (state<<8) | buf[i];
if(state>>(32-22) == 0x20){
pc->frame_start_found=0;
pc->state=-1;
return i-3;
}
}
}
pc->frame_start_found= vop_found;
pc->state= state;
return END_NOT_FOUND;
}
/**
* draws an line from (ex, ey) -> (sx, sy).
* @param w width of the image
......@@ -440,6 +476,8 @@ uint64_t time= rdtsc();
if(s->codec_id==CODEC_ID_MPEG4){
next= mpeg4_find_frame_end(s, buf, buf_size);
}else if(s->codec_id==CODEC_ID_H263){
next= h263_find_frame_end(s, buf, buf_size);
}else{
fprintf(stderr, "this codec doesnt support truncated bitstreams\n");
return -1;
......@@ -753,6 +791,7 @@ retry:
#ifdef PRINT_FRAME_TIME
printf("%Ld\n", rdtsc()-time);
#endif
return get_consumed_bytes(s, buf_size);
}
......@@ -784,7 +823,7 @@ AVCodec h263_decoder = {
NULL,
ff_h263_decode_end,
ff_h263_decode_frame,
CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1,
CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED,
};
AVCodec msmpeg4v1_decoder = {
......
......@@ -208,6 +208,22 @@ static int mpegvideo_probe(AVProbeData *p)
return 0;
}
static int h263_probe(AVProbeData *p)
{
int code;
const uint8_t *d;
if (p->buf_size < 6)
return 0;
d = p->buf;
code = (d[0] << 14) | (d[1] << 6) | (d[2] >> 2);
if (code == 0x20) {
return 50;
}
return 0;
}
AVInputFormat mp3_iformat = {
"mp3",
"MPEG audio",
......@@ -275,6 +291,18 @@ AVOutputFormat ac3_oformat = {
raw_write_trailer,
};
AVInputFormat h263_iformat = {
"h263",
"raw h263",
0,
h263_probe,
video_read_header,
raw_read_packet,
raw_read_close,
// .extensions = "h263", //FIXME remove after writing mpeg4_probe
.value = CODEC_ID_H263,
};
AVOutputFormat h263_oformat = {
"h263",
"raw h263",
......@@ -538,6 +566,7 @@ int raw_init(void)
av_register_input_format(&ac3_iformat);
av_register_output_format(&ac3_oformat);
av_register_input_format(&h263_iformat);
av_register_output_format(&h263_oformat);
av_register_input_format(&m4v_iformat);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment