Originally committed as revision 1898 to svn://svn.ffmpeg.org/ffmpeg/trunktags/v0.5
| @@ -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); | |||