Commit 7a06ff14 authored by Michael Niedermayer's avatar Michael Niedermayer

AVCodec.flush()

ff_draw_horiz_band() in coded order / cleanup

Originally committed as revision 2064 to svn://svn.ffmpeg.org/ffmpeg/trunk
parent bc351386
...@@ -15,8 +15,8 @@ extern "C" { ...@@ -15,8 +15,8 @@ extern "C" {
#define LIBAVCODEC_VERSION_INT 0x000406 #define LIBAVCODEC_VERSION_INT 0x000406
#define LIBAVCODEC_VERSION "0.4.6" #define LIBAVCODEC_VERSION "0.4.6"
#define LIBAVCODEC_BUILD 4669 #define LIBAVCODEC_BUILD 4670
#define LIBAVCODEC_BUILD_STR "4669" #define LIBAVCODEC_BUILD_STR "4670"
#define LIBAVCODEC_IDENT "FFmpeg" LIBAVCODEC_VERSION "b" LIBAVCODEC_BUILD_STR #define LIBAVCODEC_IDENT "FFmpeg" LIBAVCODEC_VERSION "b" LIBAVCODEC_BUILD_STR
...@@ -473,7 +473,7 @@ typedef struct AVCodecContext { ...@@ -473,7 +473,7 @@ typedef struct AVCodecContext {
* - decoding: set by user. * - decoding: set by user.
*/ */
void (*draw_horiz_band)(struct AVCodecContext *s, void (*draw_horiz_band)(struct AVCodecContext *s,
uint8_t **src_ptr, int linesize, AVFrame *src, int offset[4],
int y, int width, int height); int y, int width, int height);
/* audio only */ /* audio only */
...@@ -1209,6 +1209,7 @@ typedef struct AVCodec { ...@@ -1209,6 +1209,7 @@ typedef struct AVCodec {
int capabilities; int capabilities;
const AVOption *options; const AVOption *options;
struct AVCodec *next; struct AVCodec *next;
void (*flush)(AVCodecContext *);
} AVCodec; } AVCodec;
/** /**
...@@ -1400,7 +1401,12 @@ int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic); ...@@ -1400,7 +1401,12 @@ int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic);
void avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic); void avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic);
void avcodec_default_free_buffers(AVCodecContext *s); void avcodec_default_free_buffers(AVCodecContext *s);
/**
* opens / inits the AVCodecContext.
* not thread save!
*/
int avcodec_open(AVCodecContext *avctx, AVCodec *codec); int avcodec_open(AVCodecContext *avctx, AVCodec *codec);
int avcodec_decode_audio(AVCodecContext *avctx, int16_t *samples, int avcodec_decode_audio(AVCodecContext *avctx, int16_t *samples,
int *frame_size_ptr, int *frame_size_ptr,
uint8_t *buf, int buf_size); uint8_t *buf, int buf_size);
......
...@@ -723,6 +723,7 @@ AVCodec mpeg4_decoder = { ...@@ -723,6 +723,7 @@ AVCodec mpeg4_decoder = {
ff_h263_decode_frame, ff_h263_decode_frame,
CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED, CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED,
.options = mpeg4_decoptions, .options = mpeg4_decoptions,
.flush= ff_mpeg_flush,
}; };
AVCodec h263_decoder = { AVCodec h263_decoder = {
...@@ -735,6 +736,7 @@ AVCodec h263_decoder = { ...@@ -735,6 +736,7 @@ AVCodec h263_decoder = {
ff_h263_decode_end, ff_h263_decode_end,
ff_h263_decode_frame, ff_h263_decode_frame,
CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED, CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED,
.flush= ff_mpeg_flush,
}; };
AVCodec msmpeg4v1_decoder = { AVCodec msmpeg4v1_decoder = {
......
...@@ -673,7 +673,7 @@ static void decode_bgr_bitstream(HYuvContext *s, int count){ ...@@ -673,7 +673,7 @@ static void decode_bgr_bitstream(HYuvContext *s, int count){
static void draw_slice(HYuvContext *s, int y){ static void draw_slice(HYuvContext *s, int y){
int h, cy; int h, cy;
uint8_t *src_ptr[3]; int offset[4];
if(s->avctx->draw_horiz_band==NULL) if(s->avctx->draw_horiz_band==NULL)
return; return;
...@@ -686,13 +686,14 @@ static void draw_slice(HYuvContext *s, int y){ ...@@ -686,13 +686,14 @@ static void draw_slice(HYuvContext *s, int y){
}else{ }else{
cy= y; cy= y;
} }
src_ptr[0] = s->picture.data[0] + s->picture.linesize[0]*y; offset[0] = s->picture.linesize[0]*y;
src_ptr[1] = s->picture.data[1] + s->picture.linesize[1]*cy; offset[1] = s->picture.linesize[1]*cy;
src_ptr[2] = s->picture.data[2] + s->picture.linesize[2]*cy; offset[2] = s->picture.linesize[2]*cy;
offset[3] = 0;
emms_c(); emms_c();
s->avctx->draw_horiz_band(s->avctx, src_ptr, s->picture.linesize[0], y, s->width, h); s->avctx->draw_horiz_band(s->avctx, &s->picture, offset, y, s->width, h);
s->last_slice_end= y + h; s->last_slice_end= y + h;
} }
......
...@@ -2356,4 +2356,5 @@ AVCodec mpeg_decoder = { ...@@ -2356,4 +2356,5 @@ AVCodec mpeg_decoder = {
mpeg_decode_end, mpeg_decode_end,
mpeg_decode_frame, mpeg_decode_frame,
CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED, CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED,
.flush= ff_mpeg_flush,
}; };
...@@ -2725,29 +2725,26 @@ static int pix_diff_vcmp16x8(uint8_t *s1, uint8_t*s2, int stride){ //FIXME move ...@@ -2725,29 +2725,26 @@ static int pix_diff_vcmp16x8(uint8_t *s1, uint8_t*s2, int stride){ //FIXME move
* @param h is the normal height, this will be reduced automatically if needed for the last row * @param h is the normal height, this will be reduced automatically if needed for the last row
*/ */
void ff_draw_horiz_band(MpegEncContext *s, int y, int h){ void ff_draw_horiz_band(MpegEncContext *s, int y, int h){
if ( s->avctx->draw_horiz_band if (s->avctx->draw_horiz_band) {
&& (s->last_picture_ptr || s->low_delay) ) {
uint8_t *src_ptr[3]; uint8_t *src_ptr[3];
int offset; int offset[4];
h= FFMIN(h, s->height - y); h= FFMIN(h, s->height - y);
if(s->pict_type==B_TYPE && s->picture_structure == PICT_FRAME) if(s->pict_type==B_TYPE && s->picture_structure == PICT_FRAME){
offset = 0; offset[0]=
else offset[1]=
offset = y * s->linesize; offset[2]=
offset[3]= 0;
if(s->pict_type==B_TYPE || s->low_delay){ }else{
src_ptr[0] = s->current_picture.data[0] + offset; offset[0]= y * s->linesize;;
src_ptr[1] = s->current_picture.data[1] + (offset >> 2); offset[1]=
src_ptr[2] = s->current_picture.data[2] + (offset >> 2); offset[2]= (y>>1) * s->uvlinesize;;
} else { offset[3]= 0;
src_ptr[0] = s->last_picture.data[0] + offset;
src_ptr[1] = s->last_picture.data[1] + (offset >> 2);
src_ptr[2] = s->last_picture.data[2] + (offset >> 2);
} }
emms_c(); emms_c();
s->avctx->draw_horiz_band(s->avctx, src_ptr, s->linesize, s->avctx->draw_horiz_band(s->avctx, (AVFrame*)s->current_picture_ptr, offset,
y, s->width, h); y, s->width, h);
} }
} }
...@@ -3076,6 +3073,18 @@ int ff_combine_frame( MpegEncContext *s, int next, uint8_t **buf, int *buf_size) ...@@ -3076,6 +3073,18 @@ int ff_combine_frame( MpegEncContext *s, int next, uint8_t **buf, int *buf_size)
return 0; return 0;
} }
void ff_mpeg_flush(AVCodecContext *avctx){
int i;
MpegEncContext *s = avctx->priv_data;
for(i=0; i<MAX_PICTURE_COUNT; i++){
if(s->picture[i].data[0] && ( s->picture[i].type == FF_BUFFER_TYPE_INTERNAL
|| s->picture[i].type == FF_BUFFER_TYPE_USER))
avctx->release_buffer(avctx, (AVFrame*)&s->picture[i]);
}
s->last_picture_ptr = s->next_picture_ptr = NULL;
}
#ifdef CONFIG_ENCODERS #ifdef CONFIG_ENCODERS
void ff_copy_bits(PutBitContext *pb, uint8_t *src, int length) void ff_copy_bits(PutBitContext *pb, uint8_t *src, int length)
{ {
......
...@@ -713,6 +713,7 @@ void ff_emulated_edge_mc(uint8_t *buf, uint8_t *src, int linesize, int block_w, ...@@ -713,6 +713,7 @@ void ff_emulated_edge_mc(uint8_t *buf, uint8_t *src, int linesize, int block_w,
int src_x, int src_y, int w, int h); int src_x, int src_y, int w, int h);
#define END_NOT_FOUND -100 #define END_NOT_FOUND -100
int ff_combine_frame( MpegEncContext *s, int next, uint8_t **buf, int *buf_size); int ff_combine_frame( MpegEncContext *s, int next, uint8_t **buf, int *buf_size);
void ff_mpeg_flush(AVCodecContext *avctx);
void ff_print_debug_info(MpegEncContext *s, Picture *pict); void ff_print_debug_info(MpegEncContext *s, Picture *pict);
void ff_er_frame_start(MpegEncContext *s); void ff_er_frame_start(MpegEncContext *s);
......
...@@ -838,4 +838,5 @@ AVCodec svq1_decoder = { ...@@ -838,4 +838,5 @@ AVCodec svq1_decoder = {
svq1_decode_end, svq1_decode_end,
svq1_decode_frame, svq1_decode_frame,
CODEC_CAP_DR1, CODEC_CAP_DR1,
.flush= ff_mpeg_flush,
}; };
...@@ -590,39 +590,13 @@ void avcodec_init(void) ...@@ -590,39 +590,13 @@ void avcodec_init(void)
dsputil_static_init(); dsputil_static_init();
} }
/* this can be called after seeking and before trying to decode the next keyframe */ /**
* Flush buffers, should be called when seeking or when swicthing to a different stream.
*/
void avcodec_flush_buffers(AVCodecContext *avctx) void avcodec_flush_buffers(AVCodecContext *avctx)
{ {
int i; if(avctx->codec->flush)
MpegEncContext *s = avctx->priv_data; avctx->codec->flush(avctx);
switch(avctx->codec_id){
case CODEC_ID_MPEG1VIDEO:
case CODEC_ID_H263:
case CODEC_ID_RV10:
// case CODEC_ID_MJPEG:
// case CODEC_ID_MJPEGB:
case CODEC_ID_MPEG4:
case CODEC_ID_MSMPEG4V1:
case CODEC_ID_MSMPEG4V2:
case CODEC_ID_MSMPEG4V3:
case CODEC_ID_WMV1:
case CODEC_ID_WMV2:
case CODEC_ID_H263P:
case CODEC_ID_H263I:
case CODEC_ID_FLV1:
case CODEC_ID_SVQ1:
for(i=0; i<MAX_PICTURE_COUNT; i++){
if(s->picture[i].data[0] && ( s->picture[i].type == FF_BUFFER_TYPE_INTERNAL
|| s->picture[i].type == FF_BUFFER_TYPE_USER))
avctx->release_buffer(avctx, (AVFrame*)&s->picture[i]);
}
s->last_picture_ptr = s->next_picture_ptr = NULL;
break;
default:
//FIXME
break;
}
} }
void avcodec_default_free_buffers(AVCodecContext *s){ void avcodec_default_free_buffers(AVCodecContext *s){
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment