mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
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
This commit is contained in:
parent
15415af418
commit
7866eeff46
27
libav/raw.c
27
libav/raw.c
@ -81,13 +81,19 @@ static int raw_read_header(AVFormatContext *s,
|
|||||||
int raw_read_packet(AVFormatContext *s,
|
int raw_read_packet(AVFormatContext *s,
|
||||||
AVPacket *pkt)
|
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;
|
return -EIO;
|
||||||
|
|
||||||
pkt->stream_index = 0;
|
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) {
|
if (ret <= 0) {
|
||||||
av_free_packet(pkt);
|
av_free_packet(pkt);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
@ -132,7 +138,8 @@ static int video_read_header(AVFormatContext *s,
|
|||||||
st->codec.codec_type = CODEC_TYPE_VIDEO;
|
st->codec.codec_type = CODEC_TYPE_VIDEO;
|
||||||
st->codec.codec_id = s->iformat->value;
|
st->codec.codec_id = s->iformat->value;
|
||||||
/* for mjpeg, specify frame rate */
|
/* 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) {
|
if (ap) {
|
||||||
st->codec.frame_rate = ap->frame_rate;
|
st->codec.frame_rate = ap->frame_rate;
|
||||||
} else {
|
} else {
|
||||||
@ -233,6 +240,17 @@ AVOutputFormat h263_oformat = {
|
|||||||
raw_write_trailer,
|
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 = {
|
AVOutputFormat m4v_oformat = {
|
||||||
"m4v",
|
"m4v",
|
||||||
"raw MPEG4 video format",
|
"raw MPEG4 video format",
|
||||||
@ -434,6 +452,7 @@ int raw_init(void)
|
|||||||
|
|
||||||
av_register_output_format(&h263_oformat);
|
av_register_output_format(&h263_oformat);
|
||||||
|
|
||||||
|
av_register_input_format(&m4v_iformat);
|
||||||
av_register_output_format(&m4v_oformat);
|
av_register_output_format(&m4v_oformat);
|
||||||
|
|
||||||
av_register_input_format(&mpegvideo_iformat);
|
av_register_input_format(&mpegvideo_iformat);
|
||||||
|
@ -110,6 +110,23 @@ static int h263_decode_end(AVCodecContext *avctx)
|
|||||||
return 0;
|
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,
|
static int h263_decode_frame(AVCodecContext *avctx,
|
||||||
void *data, int *data_size,
|
void *data, int *data_size,
|
||||||
UINT8 *buf, int buf_size)
|
UINT8 *buf, int buf_size)
|
||||||
@ -179,20 +196,20 @@ uint64_t time= rdtsc();
|
|||||||
return -1;
|
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 */
|
/* skip if the header was thrashed */
|
||||||
if (ret < 0){
|
if (ret < 0){
|
||||||
fprintf(stderr, "header damaged\n");
|
fprintf(stderr, "header damaged\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
/* skip b frames if we dont have reference frames */
|
/* 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 */
|
/* 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->next_p_frame_damaged){
|
||||||
if(s->pict_type==B_TYPE)
|
if(s->pict_type==B_TYPE)
|
||||||
return buf_size;
|
return get_consumed_bytes(s, buf_size);
|
||||||
else
|
else
|
||||||
s->next_p_frame_damaged=0;
|
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;
|
if(msmpeg4_decode_ext_header(s, buf_size) < 0) return -1;
|
||||||
|
|
||||||
/* divx 5.01+ bistream reorder stuff */
|
/* 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;
|
int current_pos= get_bits_count(&s->gb)>>3;
|
||||||
|
|
||||||
if( buf_size - current_pos > 5
|
if( buf_size - current_pos > 5
|
||||||
&& buf_size - current_pos < BITSTREAM_BUFFER_SIZE){
|
&& buf_size - current_pos < BITSTREAM_BUFFER_SIZE){
|
||||||
int i;
|
int i;
|
||||||
int startcode_found=0;
|
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){
|
if(buf[i]==0 && buf[i+1]==0 && buf[i+2]==1 && buf[i+3]==0xB6){
|
||||||
startcode_found=1;
|
startcode_found=1;
|
||||||
break;
|
break;
|
||||||
@ -454,7 +471,7 @@ uint64_t time= rdtsc();
|
|||||||
#ifdef PRINT_FRAME_TIME
|
#ifdef PRINT_FRAME_TIME
|
||||||
printf("%Ld\n", rdtsc()-time);
|
printf("%Ld\n", rdtsc()-time);
|
||||||
#endif
|
#endif
|
||||||
return buf_size;
|
return get_consumed_bytes(s, buf_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
AVCodec mpeg4_decoder = {
|
AVCodec mpeg4_decoder = {
|
||||||
|
Loading…
Reference in New Issue
Block a user