summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2002-09-12 11:10:33 +0000
committerMichael Niedermayer <michaelni@gmx.at>2002-09-12 11:10:33 +0000
commit7866eeff46f3807696100d1061b6cd07af0dd9eb (patch)
tree3f733fa6426785509343c6a5706a1096ba916946
parent15415af4188f50a3225121c3400b5c05bcaaeda0 (diff)
m4v input support
return the correct number of bytes consumed for decding h263 like formats (needed for reading raw streams) this could break some divx files with b frames, so please tell me ASAP if u notice any problems Originally committed as revision 924 to svn://svn.ffmpeg.org/ffmpeg/trunk
-rw-r--r--libav/raw.c27
-rw-r--r--libavcodec/h263dec.c31
2 files changed, 47 insertions, 11 deletions
diff --git a/libav/raw.c b/libav/raw.c
index 47efe1af06..6cfa268e13 100644
--- a/libav/raw.c
+++ b/libav/raw.c
@@ -81,13 +81,19 @@ static int raw_read_header(AVFormatContext *s,
int raw_read_packet(AVFormatContext *s,
AVPacket *pkt)
{
- int ret;
+ int ret, size;
+ AVStream *st = s->streams[0];
+
+ if(st->codec.codec_id == CODEC_ID_MPEG4)
+ size= 1024*1024; //cant handle partial frames
+ else
+ size= RAW_PACKET_SIZE;
- if (av_new_packet(pkt, RAW_PACKET_SIZE) < 0)
+ if (av_new_packet(pkt, size) < 0)
return -EIO;
pkt->stream_index = 0;
- ret = get_buffer(&s->pb, pkt->data, RAW_PACKET_SIZE);
+ ret = get_buffer(&s->pb, pkt->data, size);
if (ret <= 0) {
av_free_packet(pkt);
return -EIO;
@@ -132,7 +138,8 @@ static int video_read_header(AVFormatContext *s,
st->codec.codec_type = CODEC_TYPE_VIDEO;
st->codec.codec_id = s->iformat->value;
/* for mjpeg, specify frame rate */
- if (st->codec.codec_id == CODEC_ID_MJPEG) {
+ /* for mpeg4 specify it too (most mpeg4 streams dont have the fixed_vop_rate set ...)*/
+ if (st->codec.codec_id == CODEC_ID_MJPEG || st->codec.codec_id == CODEC_ID_MPEG4) {
if (ap) {
st->codec.frame_rate = ap->frame_rate;
} else {
@@ -233,6 +240,17 @@ AVOutputFormat h263_oformat = {
raw_write_trailer,
};
+AVInputFormat m4v_iformat = {
+ "m4v",
+ "raw MPEG4 video format",
+ 0,
+ mpegvideo_probe,
+ video_read_header,
+ raw_read_packet,
+ raw_read_close,
+ value: CODEC_ID_MPEG4,
+};
+
AVOutputFormat m4v_oformat = {
"m4v",
"raw MPEG4 video format",
@@ -434,6 +452,7 @@ int raw_init(void)
av_register_output_format(&h263_oformat);
+ av_register_input_format(&m4v_iformat);
av_register_output_format(&m4v_oformat);
av_register_input_format(&mpegvideo_iformat);
diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c
index 0d83a5633f..4b30180db4 100644
--- a/libavcodec/h263dec.c
+++ b/libavcodec/h263dec.c
@@ -110,6 +110,23 @@ static int h263_decode_end(AVCodecContext *avctx)
return 0;
}
+/**
+ * retunrs the number of bytes consumed for building the current frame
+ */
+static int get_consumed_bytes(MpegEncContext *s, int buf_size){
+ int pos= (get_bits_count(&s->gb)+7)>>3;
+
+ if(s->divx_version>=500){
+ //we would have to scan through the whole buf to handle the weird reordering ...
+ return buf_size;
+ }else{
+ if(pos==0) pos=1; //avoid infinite loops (i doubt thats needed but ...)
+ if(pos>buf_size) pos=buf_size; // oops ;)
+
+ return pos;
+ }
+}
+
static int h263_decode_frame(AVCodecContext *avctx,
void *data, int *data_size,
UINT8 *buf, int buf_size)
@@ -179,20 +196,20 @@ uint64_t time= rdtsc();
return -1;
}
- if(ret==FRAME_SKIPED) return buf_size;
+ if(ret==FRAME_SKIPED) return get_consumed_bytes(s, buf_size);
/* skip if the header was thrashed */
if (ret < 0){
fprintf(stderr, "header damaged\n");
return -1;
}
/* skip b frames if we dont have reference frames */
- if(s->num_available_buffers<2 && s->pict_type==B_TYPE) return buf_size;
+ if(s->num_available_buffers<2 && s->pict_type==B_TYPE) return get_consumed_bytes(s, buf_size);
/* skip b frames if we are in a hurry */
- if(s->hurry_up && s->pict_type==B_TYPE) return buf_size;
+ if(s->hurry_up && s->pict_type==B_TYPE) return get_consumed_bytes(s, buf_size);
if(s->next_p_frame_damaged){
if(s->pict_type==B_TYPE)
- return buf_size;
+ return get_consumed_bytes(s, buf_size);
else
s->next_p_frame_damaged=0;
}
@@ -354,14 +371,14 @@ uint64_t time= rdtsc();
if(msmpeg4_decode_ext_header(s, buf_size) < 0) return -1;
/* divx 5.01+ bistream reorder stuff */
- if(s->codec_id==CODEC_ID_MPEG4 && s->bitstream_buffer_size==0){
+ if(s->codec_id==CODEC_ID_MPEG4 && s->bitstream_buffer_size==0 && s->divx_version>=500){
int current_pos= get_bits_count(&s->gb)>>3;
if( buf_size - current_pos > 5
&& buf_size - current_pos < BITSTREAM_BUFFER_SIZE){
int i;
int startcode_found=0;
- for(i=current_pos; i<buf_size; i++){
+ for(i=current_pos; i<buf_size-3; i++){
if(buf[i]==0 && buf[i+1]==0 && buf[i+2]==1 && buf[i+3]==0xB6){
startcode_found=1;
break;
@@ -454,7 +471,7 @@ uint64_t time= rdtsc();
#ifdef PRINT_FRAME_TIME
printf("%Ld\n", rdtsc()-time);
#endif
- return buf_size;
+ return get_consumed_bytes(s, buf_size);
}
AVCodec mpeg4_decoder = {