truncated h263 decoding support / H263-ES "demuxer"
Originally committed as revision 1898 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
e67e14d54c
commit
d07f90433a
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user