Originally committed as revision 2636 to svn://svn.ffmpeg.org/ffmpeg/trunktags/v0.5
| @@ -131,6 +131,7 @@ static int packet_size = 0; | |||
| static int error_rate = 0; | |||
| static int strict = 0; | |||
| static int debug = 0; | |||
| static int debug_mv = 0; | |||
| extern int loop_input; /* currently a hack */ | |||
| static int gop_size = 12; | |||
| @@ -1672,6 +1673,11 @@ static void opt_debug(const char *arg) | |||
| debug = atoi(arg); | |||
| } | |||
| static void opt_vismv(const char *arg) | |||
| { | |||
| debug_mv = atoi(arg); | |||
| } | |||
| static void opt_verbose(const char *arg) | |||
| { | |||
| verbose = atoi(arg); | |||
| @@ -2171,8 +2177,9 @@ static void opt_input_file(const char *filename) | |||
| enc->workaround_bugs = workaround_bugs; | |||
| enc->error_resilience = error_resilience; | |||
| enc->error_concealment = error_concealment; | |||
| enc->idct_algo= idct_algo; | |||
| enc->debug= debug; | |||
| enc->idct_algo = idct_algo; | |||
| enc->debug = debug; | |||
| enc->debug_mv = debug_mv; | |||
| if(bitexact) | |||
| enc->flags|= CODEC_FLAG_BITEXACT; | |||
| @@ -2382,8 +2389,8 @@ static void opt_output_file(const char *filename) | |||
| video_enc->qblur = video_qblur; | |||
| video_enc->qcompress = video_qcomp; | |||
| video_enc->rc_eq = video_rc_eq; | |||
| video_enc->debug= debug; | |||
| video_enc->debug = debug; | |||
| video_enc->debug_mv = debug_mv; | |||
| p= video_rc_override_string; | |||
| for(i=0; p; i++){ | |||
| int start, end, q; | |||
| @@ -2913,6 +2920,7 @@ const OptionDef options[] = { | |||
| { "copyright", HAS_ARG | OPT_STRING, {(void*)&str_copyright}, "set the copyright", "string" }, | |||
| { "comment", HAS_ARG | OPT_STRING, {(void*)&str_comment}, "set the comment", "string" }, | |||
| { "debug", HAS_ARG | OPT_EXPERT, {(void*)opt_debug}, "print specific debug info", "" }, | |||
| { "vismv", HAS_ARG | OPT_EXPERT, {(void*)opt_vismv}, "visualize motion vectors", "" }, | |||
| { "benchmark", OPT_BOOL | OPT_EXPERT, {(void*)&do_benchmark}, | |||
| "add timings for benchmarking" }, | |||
| { "dump", OPT_BOOL | OPT_EXPERT, {(void*)&do_pkt_dump}, | |||
| @@ -166,6 +166,7 @@ static int show_status; | |||
| static int av_sync_type = AV_SYNC_AUDIO_MASTER; | |||
| static int64_t start_time = AV_NOPTS_VALUE; | |||
| static int debug = 0; | |||
| static int debug_mv = 0; | |||
| static int step = 0; | |||
| /* current context */ | |||
| @@ -1196,7 +1197,8 @@ static int stream_component_open(VideoState *is, int stream_index) | |||
| packet_queue_init(&is->videoq); | |||
| is->video_tid = SDL_CreateThread(video_thread, is); | |||
| enc->debug= debug; | |||
| enc->debug = debug; | |||
| enc->debug_mv = debug_mv; | |||
| break; | |||
| default: | |||
| break; | |||
| @@ -1784,6 +1786,11 @@ static void opt_debug(const char *arg) | |||
| debug = atoi(arg); | |||
| } | |||
| static void opt_vismv(const char *arg) | |||
| { | |||
| debug_mv = atoi(arg); | |||
| } | |||
| const OptionDef options[] = { | |||
| { "h", 0, {(void*)show_help}, "show help" }, | |||
| { "x", HAS_ARG, {(void*)opt_width}, "force displayed width", "width" }, | |||
| @@ -1800,6 +1807,7 @@ const OptionDef options[] = { | |||
| { "img", HAS_ARG, {(void*)opt_image_format}, "force image format", "img_fmt" }, | |||
| { "stats", OPT_BOOL | OPT_EXPERT, {(void*)&show_status}, "show status", "" }, | |||
| { "debug", HAS_ARG | OPT_EXPERT, {(void*)opt_debug}, "print specific debug info", "" }, | |||
| { "vismv", HAS_ARG | OPT_EXPERT, {(void*)opt_vismv}, "visualize motion vectors", "" }, | |||
| #ifdef CONFIG_NETWORK | |||
| { "rtp_tcp", OPT_EXPERT, {(void*)&opt_rtp_tcp}, "force RTP/TCP protocol usage", "" }, | |||
| #endif | |||
| @@ -1133,7 +1133,7 @@ typedef struct AVCodecContext { | |||
| #define FF_DEBUG_MB_TYPE 8 | |||
| #define FF_DEBUG_QP 16 | |||
| #define FF_DEBUG_MV 32 | |||
| #define FF_DEBUG_VIS_MV 0x00000040 | |||
| //#define FF_DEBUG_VIS_MV 0x00000040 | |||
| #define FF_DEBUG_SKIP 0x00000080 | |||
| #define FF_DEBUG_STARTCODE 0x00000100 | |||
| #define FF_DEBUG_PTS 0x00000200 | |||
| @@ -1143,6 +1143,16 @@ typedef struct AVCodecContext { | |||
| #define FF_DEBUG_VIS_QP 0x00002000 | |||
| #define FF_DEBUG_VIS_MB_TYPE 0x00004000 | |||
| /** | |||
| * debug. | |||
| * - encoding: set by user. | |||
| * - decoding: set by user. | |||
| */ | |||
| int debug_mv; | |||
| #define FF_DEBUG_VIS_MV_P_FOR 0x00000001 //visualize forward predicted MVs of P frames | |||
| #define FF_DEBUG_VIS_MV_B_FOR 0x00000002 //visualize forward predicted MVs of B frames | |||
| #define FF_DEBUG_VIS_MV_B_BACK 0x00000004 //visualize backward predicted MVs of B frames | |||
| /** | |||
| * error. | |||
| * - encoding: set by lavc if flags&CODEC_FLAG_PSNR | |||
| @@ -703,10 +703,10 @@ 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; | |||
| ff_print_debug_info(s, s->current_picture_ptr); | |||
| ff_print_debug_info(s, pict); | |||
| } else { | |||
| *pict= *(AVFrame*)&s->last_picture; | |||
| ff_print_debug_info(s, s->last_picture_ptr); | |||
| ff_print_debug_info(s, pict); | |||
| } | |||
| /* Return the Picture timestamp as the frame number */ | |||
| @@ -4172,7 +4172,7 @@ static int decode_frame(AVCodecContext *avctx, | |||
| } | |||
| *pict= *(AVFrame*)&s->current_picture; //FIXME | |||
| ff_print_debug_info(s, s->current_picture_ptr); | |||
| ff_print_debug_info(s, pict); | |||
| assert(pict->data[0]); | |||
| //printf("out %d\n", (int)pict->data[0]); | |||
| #if 0 //? | |||
| @@ -2305,14 +2305,14 @@ static int slice_end(AVCodecContext *avctx, AVFrame *pict) | |||
| if (s->pict_type == B_TYPE || s->low_delay) { | |||
| *pict= *(AVFrame*)s->current_picture_ptr; | |||
| ff_print_debug_info(s, s->current_picture_ptr); | |||
| ff_print_debug_info(s, pict); | |||
| } else { | |||
| s->picture_number++; | |||
| /* latency of 1 frame for I and P frames */ | |||
| /* XXX: use another variable than picture_number */ | |||
| if (s->last_picture_ptr != NULL) { | |||
| *pict= *(AVFrame*)s->last_picture_ptr; | |||
| ff_print_debug_info(s, s->last_picture_ptr); | |||
| ff_print_debug_info(s, pict); | |||
| } | |||
| } | |||
| @@ -337,7 +337,7 @@ static int alloc_picture(MpegEncContext *s, Picture *pic, int shared){ | |||
| CHECKED_ALLOCZ(pic->ref_index[i] , b8_array_size * sizeof(uint8_t)) | |||
| } | |||
| pic->motion_subsample_log2= 2; | |||
| }else if(s->out_format == FMT_H263 || s->encoding || (s->avctx->debug&(FF_DEBUG_VIS_MV|FF_DEBUG_MV))){ | |||
| }else if(s->out_format == FMT_H263 || s->encoding || (s->avctx->debug&FF_DEBUG_MV) || (s->avctx->debug_mv)){ | |||
| for(i=0; i<2; i++){ | |||
| CHECKED_ALLOCZ(pic->motion_val_base[i], 2 * (b8_array_size+1) * sizeof(uint16_t)*2) //FIXME | |||
| pic->motion_val[i]= pic->motion_val_base[i]+1; | |||
| @@ -564,6 +564,11 @@ int MPV_common_init(MpegEncContext *s) | |||
| } | |||
| s->parse_context.state= -1; | |||
| if((s->avctx->debug&(FF_DEBUG_VIS_QP|FF_DEBUG_VIS_MB_TYPE)) || (s->avctx->debug_mv)){ | |||
| s->visualization_buffer[0] = av_malloc((s->mb_width*16 + 2*EDGE_WIDTH) * s->mb_height*16 + 2*EDGE_WIDTH); | |||
| s->visualization_buffer[1] = av_malloc((s->mb_width*8 + EDGE_WIDTH) * s->mb_height*8 + EDGE_WIDTH); | |||
| s->visualization_buffer[2] = av_malloc((s->mb_width*8 + EDGE_WIDTH) * s->mb_height*8 + EDGE_WIDTH); | |||
| } | |||
| s->context_initialized = 1; | |||
| return 0; | |||
| @@ -641,6 +646,9 @@ void MPV_common_end(MpegEncContext *s) | |||
| s->last_picture_ptr= | |||
| s->next_picture_ptr= | |||
| s->current_picture_ptr= NULL; | |||
| for(i=0; i<3; i++) | |||
| if (s->visualization_buffer[i]) | |||
| av_free(s->visualization_buffer[i]); | |||
| } | |||
| #ifdef CONFIG_ENCODERS | |||
| @@ -1361,13 +1369,22 @@ static void draw_arrow(uint8_t *buf, int sx, int sy, int ex, int ey, int w, int | |||
| /** | |||
| * prints debuging info for the given picture. | |||
| */ | |||
| void ff_print_debug_info(MpegEncContext *s, Picture *pict){ | |||
| void ff_print_debug_info(MpegEncContext *s, AVFrame *pict){ | |||
| if(!pict || !pict->mb_type) return; | |||
| if(s->avctx->debug&(FF_DEBUG_SKIP | FF_DEBUG_QP | FF_DEBUG_MB_TYPE)){ | |||
| int x,y; | |||
| av_log(s->avctx,AV_LOG_DEBUG,"New frame, type: "); | |||
| switch (pict->pict_type) { | |||
| case FF_I_TYPE: av_log(s->avctx,AV_LOG_DEBUG,"I\n"); break; | |||
| case FF_P_TYPE: av_log(s->avctx,AV_LOG_DEBUG,"P\n"); break; | |||
| case FF_B_TYPE: av_log(s->avctx,AV_LOG_DEBUG,"B\n"); break; | |||
| case FF_S_TYPE: av_log(s->avctx,AV_LOG_DEBUG,"S\n"); break; | |||
| case FF_SI_TYPE: av_log(s->avctx,AV_LOG_DEBUG,"SI\n"); break; | |||
| case FF_SP_TYPE: av_log(s->avctx,AV_LOG_DEBUG,"SP\n"); break; | |||
| } | |||
| for(y=0; y<s->mb_height; y++){ | |||
| for(x=0; x<s->mb_width; x++){ | |||
| if(s->avctx->debug&FF_DEBUG_SKIP){ | |||
| @@ -1380,7 +1397,6 @@ void ff_print_debug_info(MpegEncContext *s, Picture *pict){ | |||
| } | |||
| if(s->avctx->debug&FF_DEBUG_MB_TYPE){ | |||
| int mb_type= pict->mb_type[x + y*s->mb_stride]; | |||
| //Type & MV direction | |||
| if(IS_PCM(mb_type)) | |||
| av_log(s->avctx, AV_LOG_DEBUG, "P"); | |||
| @@ -1433,45 +1449,71 @@ void ff_print_debug_info(MpegEncContext *s, Picture *pict){ | |||
| } | |||
| } | |||
| if(s->avctx->debug&(FF_DEBUG_VIS_MV|FF_DEBUG_VIS_QP|FF_DEBUG_VIS_MB_TYPE)){ | |||
| if((s->avctx->debug&(FF_DEBUG_VIS_QP|FF_DEBUG_VIS_MB_TYPE)) || (s->avctx->debug_mv)){ | |||
| const int shift= 1 + s->quarter_sample; | |||
| int mb_y; | |||
| uint8_t *ptr= pict->data[0]; | |||
| uint8_t *ptr; | |||
| s->low_delay=0; //needed to see the vectors without trashing the buffers | |||
| int i; | |||
| for(i=0; i<3; i++){ | |||
| memcpy(s->visualization_buffer[i], pict->data[i], (i==0) ? pict->linesize[i]*s->height:pict->linesize[i]*s->height/2); | |||
| pict->data[i]= s->visualization_buffer[i]; | |||
| } | |||
| pict->type= FF_BUFFER_TYPE_COPY; | |||
| ptr= pict->data[0]; | |||
| for(mb_y=0; mb_y<s->mb_height; mb_y++){ | |||
| int mb_x; | |||
| for(mb_x=0; mb_x<s->mb_width; mb_x++){ | |||
| const int mb_index= mb_x + mb_y*s->mb_stride; | |||
| if((s->avctx->debug&FF_DEBUG_VIS_MV) && pict->motion_val){ | |||
| if(IS_8X8(pict->mb_type[mb_index])){ | |||
| int i; | |||
| for(i=0; i<4; i++){ | |||
| if((s->avctx->debug_mv) && pict->motion_val){ | |||
| int type; | |||
| for(type=0; type<3; type++){ | |||
| int direction; | |||
| switch (type) { | |||
| case 0: if ((!(s->avctx->debug_mv&FF_DEBUG_VIS_MV_P_FOR)) || (pict->pict_type!=FF_P_TYPE)) | |||
| continue; | |||
| direction = 0; | |||
| break; | |||
| case 1: if ((!(s->avctx->debug_mv&FF_DEBUG_VIS_MV_B_FOR)) || (pict->pict_type!=FF_B_TYPE)) | |||
| continue; | |||
| direction = 0; | |||
| break; | |||
| case 2: if ((!(s->avctx->debug_mv&FF_DEBUG_VIS_MV_B_BACK)) || (pict->pict_type!=FF_B_TYPE)) | |||
| continue; | |||
| direction = 1; | |||
| break; | |||
| } | |||
| if(IS_8X8(pict->mb_type[mb_index])){ | |||
| int i; | |||
| for(i=0; i<4; i++){ | |||
| int sx= mb_x*16 + 4 + 8*(i&1); | |||
| int sy= mb_y*16 + 4 + 8*(i>>1); | |||
| int xy= 1 + mb_x*2 + (i&1) + (mb_y*2 + 1 + (i>>1))*(s->mb_width*2 + 2); | |||
| int mx= (pict->motion_val[0][xy][0]>>shift) + sx; | |||
| int my= (pict->motion_val[0][xy][1]>>shift) + sy; | |||
| int mx= (pict->motion_val[direction][xy][0]>>shift) + sx; | |||
| int my= (pict->motion_val[direction][xy][1]>>shift) + sy; | |||
| draw_arrow(ptr, sx, sy, mx, my, s->width, s->height, s->linesize, 100); | |||
| } | |||
| }else if(IS_16X8(pict->mb_type[mb_index])){ | |||
| int i; | |||
| for(i=0; i<2; i++){ | |||
| } | |||
| }else if(IS_16X8(pict->mb_type[mb_index])){ | |||
| int i; | |||
| for(i=0; i<2; i++){ | |||
| int sx=mb_x*16 + 8; | |||
| int sy=mb_y*16 + 4 + 8*i; | |||
| int xy=1 + mb_x*2 + (mb_y*2 + 1 + i)*(s->mb_width*2 + 2); | |||
| int mx=(pict->motion_val[0][xy][0]>>shift) + sx; | |||
| int my=(pict->motion_val[0][xy][1]>>shift) + sy; | |||
| int mx=(pict->motion_val[direction][xy][0]>>shift) + sx; | |||
| int my=(pict->motion_val[direction][xy][1]>>shift) + sy; | |||
| draw_arrow(ptr, sx, sy, mx, my, s->width, s->height, s->linesize, 100); | |||
| } | |||
| }else{ | |||
| int sx= mb_x*16 + 8; | |||
| int sy= mb_y*16 + 8; | |||
| int xy= 1 + mb_x*2 + (mb_y*2 + 1)*(s->mb_width*2 + 2); | |||
| int mx= (pict->motion_val[direction][xy][0]>>shift) + sx; | |||
| int my= (pict->motion_val[direction][xy][1]>>shift) + sy; | |||
| draw_arrow(ptr, sx, sy, mx, my, s->width, s->height, s->linesize, 100); | |||
| } | |||
| }else{ | |||
| int sx= mb_x*16 + 8; | |||
| int sy= mb_y*16 + 8; | |||
| int xy= 1 + mb_x*2 + (mb_y*2 + 1)*(s->mb_width*2 + 2); | |||
| int mx= (pict->motion_val[0][xy][0]>>shift) + sx; | |||
| int my= (pict->motion_val[0][xy][1]>>shift) + sy; | |||
| draw_arrow(ptr, sx, sy, mx, my, s->width, s->height, s->linesize, 100); | |||
| } | |||
| } | |||
| } | |||
| if((s->avctx->debug&FF_DEBUG_VIS_QP) && pict->motion_val){ | |||
| uint64_t c= (pict->qscale_table[mb_index]*128/31) * 0x0101010101010101ULL; | |||
| @@ -304,6 +304,7 @@ typedef struct MpegEncContext { | |||
| Picture *last_picture_ptr; ///< pointer to the previous picture. | |||
| Picture *next_picture_ptr; ///< pointer to the next picture (for bidir pred) | |||
| Picture *current_picture_ptr; ///< pointer to the current picture | |||
| uint8_t *visualization_buffer[3]; //< temporary buffer vor MV visualization | |||
| int last_dc[3]; ///< last DC values for MPEG1 | |||
| int16_t *dc_val[3]; ///< used for mpeg4 DC prediction, all 3 arrays must be continuous | |||
| int16_t dc_cache[4*5]; | |||
| @@ -705,7 +706,7 @@ void ff_emulated_edge_mc(uint8_t *buf, uint8_t *src, int linesize, int block_w, | |||
| #define END_NOT_FOUND -100 | |||
| 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, AVFrame *pict); | |||
| void ff_write_quant_matrix(PutBitContext *pb, int16_t *matrix); | |||
| int ff_find_unused_picture(MpegEncContext *s, int shared); | |||
| void ff_denoise_dct(MpegEncContext *s, DCTELEM *block); | |||
| @@ -662,10 +662,10 @@ static int rv10_decode_frame(AVCodecContext *avctx, | |||
| if(s->pict_type==B_TYPE || s->low_delay){ | |||
| *pict= *(AVFrame*)&s->current_picture; | |||
| ff_print_debug_info(s, s->current_picture_ptr); | |||
| ff_print_debug_info(s, pict); | |||
| } else { | |||
| *pict= *(AVFrame*)&s->last_picture; | |||
| ff_print_debug_info(s, s->last_picture_ptr); | |||
| ff_print_debug_info(s, pict); | |||
| } | |||
| *data_size = sizeof(AVFrame); | |||