[FFmpeg-soc] [soc]: r372 - rv40/rv40.c
kostya
subversion at mplayerhq.hu
Wed Jul 11 09:14:26 CEST 2007
Author: kostya
Date: Wed Jul 11 09:14:26 2007
New Revision: 372
Log:
RV40 is slice-based and passes each slice in its own packet (like RV10/20)
So switch decoding process to handling one slice a time
Modified:
rv40/rv40.c
Modified: rv40/rv40.c
==============================================================================
--- rv40/rv40.c (original)
+++ rv40/rv40.c Wed Jul 11 09:14:26 2007
@@ -40,9 +40,10 @@ typedef struct RV40DecContext{
int mb_bits; ///< bits needed to read MB offet in slice header
int intra_types[16]; ///< block types
int block_start; ///< start of slice in blocks
- int block_end; ///< end of slice in blocks
int ptype; ///< picture type
int quant; ///< quantizer
+
+ int bits; ///< slice size in bits
}RV40DecContext;
@@ -462,7 +463,7 @@ static int rv40_parse_slice_header(RV40D
r->s.avctx->coded_height = h;
mb_bits = av_log2((w + 7) >> 3) + av_log2((h + 7) >> 3);
r->block_start = get_bits(gb, mb_bits);
- r->block_end = r->block_start+70;
+
return 0;
}
@@ -609,17 +610,25 @@ static int rv40_decode_macroblock(RV40De
return 0;
}
-static int rv40_decode_slice(RV40DecContext *r, int slice_start, int slice_end)
+static int rv40_decode_slice(RV40DecContext *r)
{
MpegEncContext *s = &r->s;
+ int mb_pos;
- ff_er_add_slice(s, 0, 0, s->mb_width - 1, s->mb_height - 1, (AC_END|DC_END|MV_END));
+ //ff_er_add_slice(s, 0, 0, s->mb_width - 1, s->mb_height - 1, (AC_END|DC_END|MV_END));
+ mb_pos = s->mb_x + s->mb_y * s->mb_width;
+ if(r->block_start != mb_pos){
+ av_log(s->avctx, AV_LOG_ERROR, "Slice indicates MB offset %d, got %d\n", r->block_start, mb_pos);
+ s->mb_x = r->block_start % s->mb_width;
+ s->mb_y = r->block_start / s->mb_width;
+ }
memset(r->intra_types, -1, 16 * sizeof(int));
s->first_slice_line = 1;
s->resync_mb_x= s->mb_x;
ff_init_block_index(s);
- for(s->mb_num_left= slice_end-slice_start; s->mb_num_left>0; s->mb_num_left--) {
+ //XXX: better bounds detection?
+ while((get_bits_count(&s->gb) + 5 < r->bits) && (s->mb_y < s->mb_height)) {
ff_update_block_index(s);
s->dsp.clear_blocks(s->block[0]);
@@ -633,7 +642,7 @@ static int rv40_decode_slice(RV40DecCont
if(s->mb_x == s->resync_mb_x)
s->first_slice_line=0;
}
- //ff_er_add_slice(s, slice_start % s->mb_width, s->resync_mb_y, s->mb_x-1, s->mb_y, AC_END|DC_END|MV_END);
+ ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, AC_END|DC_END|MV_END);
return 0;
}
@@ -688,97 +697,43 @@ static int rv40_decode_frame(AVCodecCont
/* no supplementary picture */
if (buf_size == 0) {
- /* special case for last picture */
- if (s->low_delay==0 && s->next_picture_ptr) {
- *pict= *(AVFrame*)s->next_picture_ptr;
- s->next_picture_ptr= NULL;
-
- *data_size = sizeof(AVFrame);
- }
-
return 0;
}
- /* We need to set current_picture_ptr before reading the header,
- * otherwise we cannot store anything in there. */
- if(s->current_picture_ptr==NULL || s->current_picture_ptr->data[0]){
- int i= ff_find_unused_picture(s, 0);
- s->current_picture_ptr= &s->picture[i];
- }
-
init_get_bits(&s->gb, buf, buf_size*8);
+ r->bits = buf_size * 8;
rv40_parse_slice_header(r, &r->s.gb);
s->pict_type = r->ptype+1;
- if(s->pict_type != I_TYPE) return -1;
- init_get_bits(&s->gb, buf, buf_size*8);
-
- // for hurry_up==5
- s->current_picture.pict_type= s->pict_type;
- s->current_picture.key_frame= s->pict_type == I_TYPE;
-
- /* skip B-frames if we don't have reference frames */
- if(s->last_picture_ptr==NULL && (s->pict_type==B_TYPE || s->dropable))
- return -1;//buf_size;
- /* skip b frames if we are in a hurry */
- if(avctx->hurry_up && s->pict_type==B_TYPE) return -1;//buf_size;
- if( (avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type==B_TYPE)
- || (avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type!=I_TYPE)
- || avctx->skip_frame >= AVDISCARD_ALL)
- return buf_size;
-
- /* skip everything if we are in a hurry>=5 */
- if(avctx->hurry_up>=5)
- return -1;//buf_size;
-
- if(s->next_p_frame_damaged){
- if(s->pict_type==B_TYPE)
- return buf_size;
- else
- s->next_p_frame_damaged=0;
- }
-
- if(MPV_frame_start(s, avctx) < 0)
- return -1;
-
- ff_er_frame_start(s);
-
- s->mb_x = s->mb_y = 0;
-
-{
-int starts[] = { 0x000, 0x046, 0x08A, 0x0BF, 0x0FE, 0x13E, 0x190, 0x205, 0x244, 0x29D, 0x2A8};
-int i;
-// do{
- for(i=0; i < 10; i++){
- if(rv40_parse_slice_header(r, &r->s.gb) < 0) break;
- res = rv40_decode_slice(r, starts[i], starts[i+1]);
+if(s->pict_type != I_TYPE)return -1;
+ if ((s->mb_x == 0 && s->mb_y == 0) || s->current_picture_ptr==NULL) {
+ if(s->current_picture_ptr){ //FIXME write parser so we always have complete frames?
+ ff_er_frame_end(s);
+ MPV_frame_end(s);
+ s->mb_x= s->mb_y = s->resync_mb_x = s->resync_mb_y= 0;
+ }
+ if(MPV_frame_start(s, avctx) < 0)
+ return -1;
+ ff_er_frame_start(s);
}
-// }while(res);
-}
- s->pict_type = r->ptype;
- s->current_picture.pict_type = s->pict_type;
-
- ff_er_frame_end(s);
-
- MPV_frame_end(s);
+ rv40_decode_slice(r);
-assert(s->current_picture.pict_type == s->current_picture_ptr->pict_type);
-assert(s->current_picture.pict_type == s->pict_type);
- if (s->pict_type == B_TYPE || s->low_delay) {
- *pict= *(AVFrame*)s->current_picture_ptr;
- } else if (s->last_picture_ptr != NULL) {
- *pict= *(AVFrame*)s->last_picture_ptr;
- }
+ if(s->current_picture_ptr != NULL && s->mb_y>=s->mb_height){
+ ff_er_frame_end(s);
+ MPV_frame_end(s);
+ if (s->pict_type == B_TYPE || s->low_delay) {
+ *pict= *(AVFrame*)s->current_picture_ptr;
+ } else if (s->last_picture_ptr != NULL) {
+ *pict= *(AVFrame*)s->last_picture_ptr;
+ }
- if(s->last_picture_ptr || s->low_delay){
- *data_size = sizeof(AVFrame);
- ff_print_debug_info(s, pict);
+ if(s->last_picture_ptr || s->low_delay){
+ *data_size = sizeof(AVFrame);
+ ff_print_debug_info(s, pict);
+ }
+ s->current_picture_ptr= NULL; //so we can detect if frame_end wasnt called (find some nicer solution...)
}
- /* Return the Picture timestamp as the frame number */
- /* we substract 1 because it is added on utils.c */
- avctx->frame_number = s->picture_number - 1;
-
return buf_size;
}
More information about the FFmpeg-soc
mailing list