summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libavcodec/h263.c58
-rw-r--r--libavcodec/h263dec.c41
-rw-r--r--libavformat/raw.c29
3 files changed, 115 insertions, 13 deletions
diff --git a/libavcodec/h263.c b/libavcodec/h263.c
index cfaec76b56..5b3119ac9c 100644
--- a/libavcodec/h263.c
+++ b/libavcodec/h263.c
@@ -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;
}
diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c
index 4f42489ccc..5ba0e16291 100644
--- a/libavcodec/h263dec.c
+++ b/libavcodec/h263dec.c
@@ -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 = {
diff --git a/libavformat/raw.c b/libavformat/raw.c
index 1c528c17a0..2354ad15cf 100644
--- a/libavformat/raw.c
+++ b/libavformat/raw.c
@@ -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);