adding AVVideoFrame moving quality, pict_type, key_frame, qscale_table, ... to AVVideoFrame removing obsolete variables in AVCodecContext skiping of MBs in b frames correctly initalizing AVCodecContext picture buffer cleanup Originally committed as revision 1302 to svn://svn.ffmpeg.org/ffmpeg/trunktags/v0.5
| @@ -285,6 +285,7 @@ int read_ffserver_streams(AVFormatContext *s, const char *filename) | |||
| s->nb_streams = ic->nb_streams; | |||
| for(i=0;i<ic->nb_streams;i++) { | |||
| AVStream *st; | |||
| st = av_mallocz(sizeof(AVFormatContext)); | |||
| memcpy(st, ic->streams[i], sizeof(AVStream)); | |||
| s->streams[i] = st; | |||
| @@ -605,15 +606,21 @@ static void do_video_out(AVFormatContext *s, | |||
| /* XXX: pb because no interleaving */ | |||
| for(i=0;i<nb_frames;i++) { | |||
| if (enc->codec_id != CODEC_ID_RAWVIDEO) { | |||
| AVVideoFrame big_picture; | |||
| memset(&big_picture, 0, sizeof(AVVideoFrame)); | |||
| *(AVPicture*)&big_picture= *picture; | |||
| /* handles sameq here. This is not correct because it may | |||
| not be a global option */ | |||
| if (same_quality) { | |||
| enc->quality = dec->quality; | |||
| } | |||
| big_picture.quality = ist->st->quality; | |||
| }else | |||
| big_picture.quality = ost->st->quality; | |||
| ret = avcodec_encode_video(enc, | |||
| video_buffer, VIDEO_BUFFER_SIZE, | |||
| picture); | |||
| &big_picture); | |||
| //enc->frame_number = enc->real_pict_num; | |||
| av_write_frame(s, ost->index, video_buffer, ret); | |||
| *frame_size = ret; | |||
| @@ -674,7 +681,7 @@ static void do_video_stats(AVFormatContext *os, AVOutputStream *ost, | |||
| total_size += frame_size; | |||
| if (enc->codec_type == CODEC_TYPE_VIDEO) { | |||
| frame_number = ost->frame_number; | |||
| fprintf(fvstats, "frame= %5d q= %2d ", frame_number, enc->quality); | |||
| fprintf(fvstats, "frame= %5d q= %2.1f ", frame_number, enc->coded_picture->quality); | |||
| if (do_psnr) | |||
| fprintf(fvstats, "PSNR= %6.2f ", enc->psnr_y); | |||
| @@ -688,7 +695,7 @@ static void do_video_stats(AVFormatContext *os, AVOutputStream *ost, | |||
| avg_bitrate = (double)(total_size * 8) / ti1 / 1000.0; | |||
| fprintf(fvstats, "s_size= %8.0fkB time= %0.3f br= %7.1fkbits/s avg_br= %7.1fkbits/s ", | |||
| (double)total_size / 1024, ti1, bitrate, avg_bitrate); | |||
| fprintf(fvstats,"type= %s\n", enc->key_frame == 1 ? "I" : "P"); | |||
| fprintf(fvstats,"type= %s\n", enc->coded_picture->key_frame == 1 ? "I" : "P"); | |||
| } | |||
| } | |||
| @@ -731,13 +738,13 @@ void print_report(AVFormatContext **output_files, | |||
| os = output_files[ost->file_index]; | |||
| enc = &ost->st->codec; | |||
| if (vid && enc->codec_type == CODEC_TYPE_VIDEO) { | |||
| sprintf(buf + strlen(buf), "q=%2d ", | |||
| enc->quality); | |||
| sprintf(buf + strlen(buf), "q=%2.1f ", | |||
| enc->coded_picture->quality); | |||
| } | |||
| if (!vid && enc->codec_type == CODEC_TYPE_VIDEO) { | |||
| frame_number = ost->frame_number; | |||
| sprintf(buf + strlen(buf), "frame=%5d q=%2d ", | |||
| frame_number, enc->quality); | |||
| sprintf(buf + strlen(buf), "frame=%5d q=%2.1f ", | |||
| frame_number, enc->coded_picture ? enc->coded_picture->quality : 0); | |||
| if (do_psnr) | |||
| sprintf(buf + strlen(buf), "PSNR=%6.2f ", enc->psnr_y); | |||
| vid = 1; | |||
| @@ -1236,9 +1243,13 @@ static int av_encode(AVFormatContext **output_files, | |||
| ist->st->codec.height); | |||
| ret = len; | |||
| } else { | |||
| AVVideoFrame big_picture; | |||
| data_size = (ist->st->codec.width * ist->st->codec.height * 3) / 2; | |||
| ret = avcodec_decode_video(&ist->st->codec, | |||
| &picture, &got_picture, ptr, len); | |||
| &big_picture, &got_picture, ptr, len); | |||
| picture= *(AVPicture*)&big_picture; | |||
| ist->st->quality= big_picture.quality; | |||
| if (ret < 0) { | |||
| fail_decode: | |||
| fprintf(stderr, "Error while decoding stream #%d.%d\n", | |||
| @@ -2046,6 +2057,7 @@ void opt_output_file(const char *filename) | |||
| fprintf(stderr, "Could not alloc stream\n"); | |||
| exit(1); | |||
| } | |||
| avcodec_get_context_defaults(&st->codec); | |||
| video_enc = &st->codec; | |||
| if (video_stream_copy) { | |||
| @@ -2074,7 +2086,7 @@ void opt_output_file(const char *filename) | |||
| video_enc->gop_size = 0; | |||
| if (video_qscale || same_quality) { | |||
| video_enc->flags |= CODEC_FLAG_QSCALE; | |||
| video_enc->quality = video_qscale; | |||
| st->quality = video_qscale; | |||
| } | |||
| if (use_hq) { | |||
| @@ -2181,6 +2193,7 @@ void opt_output_file(const char *filename) | |||
| fprintf(stderr, "Could not alloc stream\n"); | |||
| exit(1); | |||
| } | |||
| avcodec_get_context_defaults(&st->codec); | |||
| audio_enc = &st->codec; | |||
| audio_enc->codec_type = CODEC_TYPE_AUDIO; | |||
| @@ -1955,7 +1955,7 @@ int av_read_frame(AVFormatContext *s, AVPacket *pkt) | |||
| /* we use the codec indication because it is | |||
| more accurate than the demux flags */ | |||
| pkt->flags = 0; | |||
| if (st->codec.key_frame) | |||
| if (st->codec.coded_picture->key_frame) | |||
| pkt->flags |= PKT_FLAG_KEY; | |||
| return 0; | |||
| } | |||
| @@ -3942,7 +3942,7 @@ int parse_ffconfig(const char *filename) | |||
| } else if (!strcasecmp(cmd, "AudioQuality")) { | |||
| get_arg(arg, sizeof(arg), &p); | |||
| if (stream) { | |||
| audio_enc.quality = atof(arg) * 1000; | |||
| // audio_enc.quality = atof(arg) * 1000; | |||
| } | |||
| } else if (!strcasecmp(cmd, "VideoBitRateRange")) { | |||
| if (stream) { | |||
| @@ -5,8 +5,8 @@ | |||
| #define LIBAVCODEC_VERSION_INT 0x000406 | |||
| #define LIBAVCODEC_VERSION "0.4.6" | |||
| #define LIBAVCODEC_BUILD 4640 | |||
| #define LIBAVCODEC_BUILD_STR "4640" | |||
| #define LIBAVCODEC_BUILD 4641 | |||
| #define LIBAVCODEC_BUILD_STR "4641" | |||
| enum CodecID { | |||
| CODEC_ID_NONE, | |||
| @@ -140,7 +140,6 @@ static const int Motion_Est_QTab[] = { ME_ZERO, ME_PHODS, ME_LOG, | |||
| #define CODEC_FLAG_EXTERN_HUFF 0x1000 /* use external huffman table (for mjpeg) */ | |||
| #define CODEC_FLAG_GRAY 0x2000 /* only decode/encode grayscale */ | |||
| #define CODEC_FLAG_EMU_EDGE 0x4000/* dont draw edges */ | |||
| #define CODEC_FLAG_DR1 0x8000 /* direct renderig type 1 (store internal frames in external buffers) */ | |||
| #define CODEC_FLAG_TRUNCATED 0x00010000 /* input bitstream might be truncated at a random location instead | |||
| of only at frame boundaries */ | |||
| #define CODEC_FLAG_NORMALIZE_AQP 0x00020000 /* normalize adaptive quantization */ | |||
| @@ -159,6 +158,111 @@ static const int Motion_Est_QTab[] = { ME_ZERO, ME_PHODS, ME_LOG, | |||
| #define FRAME_RATE_BASE 10000 | |||
| #define FF_COMMON_PICTURE \ | |||
| uint8_t *data[4];\ | |||
| int linesize[4];\ | |||
| /**\ | |||
| * pointer to the first allocated byte of the picture. can be used in get_buffer/release_buffer | |||
| * this isnt used by lavc unless the default get/release_buffer() is used\ | |||
| * encoding: \ | |||
| * decoding: \ | |||
| */\ | |||
| uint8_t *base[4];\ | |||
| /**\ | |||
| * 1 -> keyframe, 0-> not\ | |||
| * encoding: set by lavc\ | |||
| * decoding: set by lavc\ | |||
| */\ | |||
| int key_frame;\ | |||
| \ | |||
| /**\ | |||
| * picture type of the frame, see ?_TYPE below\ | |||
| * encoding: set by lavc for coded_picture (and set by user for input)\ | |||
| * decoding: set by lavc\ | |||
| */\ | |||
| int pict_type;\ | |||
| \ | |||
| /**\ | |||
| * presentation timestamp in micro seconds (time when frame should be shown to user)\ | |||
| * if 0 then the frame_rate will be used as reference\ | |||
| * encoding: MUST be set by user\ | |||
| * decoding: set by lavc\ | |||
| */\ | |||
| long long int pts;\ | |||
| \ | |||
| /**\ | |||
| * picture number in bitstream order.\ | |||
| * encoding: set by\ | |||
| * decoding: set by lavc\ | |||
| */\ | |||
| int coded_picture_number;\ | |||
| /**\ | |||
| * encoding: set by\ | |||
| * decoding: set by lavc\ | |||
| * picture number in display order.\ | |||
| */\ | |||
| int display_picture_number;\ | |||
| \ | |||
| /**\ | |||
| * quality (between 1 (good) and 31 (bad)) \ | |||
| * encoding: set by lavc for coded_picture (and set by user for input)\ | |||
| * decoding: set by lavc\ | |||
| */\ | |||
| float quality; \ | |||
| \ | |||
| /**\ | |||
| * buffer age (1->was last buffer and dint change, 2->..., ...).\ | |||
| * set to something large if the buffer has not been used yet \ | |||
| * encoding: unused\ | |||
| * decoding: MUST be set by get_buffer()\ | |||
| */\ | |||
| int age;\ | |||
| \ | |||
| /**\ | |||
| * is this picture used as reference\ | |||
| * encoding: unused\ | |||
| * decoding: set by lavc (before get_buffer() call))\ | |||
| */\ | |||
| int reference;\ | |||
| \ | |||
| /**\ | |||
| * QP table\ | |||
| * encoding: unused\ | |||
| * decoding: set by lavc\ | |||
| */\ | |||
| int8_t *qscale_table;\ | |||
| /**\ | |||
| * QP store stride\ | |||
| * encoding: unused\ | |||
| * decoding: set by lavc\ | |||
| */\ | |||
| int qstride;\ | |||
| \ | |||
| /**\ | |||
| * mbskip_table[mb]>=1 if MB didnt change\ | |||
| * stride= mb_width = (width+15)>>4\ | |||
| * encoding: unused\ | |||
| * decoding: set by lavc\ | |||
| */\ | |||
| uint8_t *mbskip_table;\ | |||
| \ | |||
| /**\ | |||
| * for some private data of the user\ | |||
| * encoding: unused\ | |||
| * decoding: set by user\ | |||
| */\ | |||
| void *opaque;\ | |||
| /* FIXME: these should have FF_ */ | |||
| #define I_TYPE 1 // Intra | |||
| #define P_TYPE 2 // Predicted | |||
| #define B_TYPE 3 // Bi-dir predicted | |||
| #define S_TYPE 4 // S(GMC)-VOP MPEG4 | |||
| typedef struct AVVideoFrame { | |||
| FF_COMMON_PICTURE | |||
| } AVVideoFrame; | |||
| typedef struct AVCodecContext { | |||
| /** | |||
| * the average bitrate | |||
| @@ -191,7 +295,7 @@ typedef struct AVCodecContext { | |||
| /** | |||
| * motion estimation algorithm used for video coding | |||
| * encoding: set by user. | |||
| * encoding: MUST be set by user. | |||
| * decoding: unused | |||
| */ | |||
| int me_method; | |||
| @@ -212,21 +316,17 @@ typedef struct AVCodecContext { | |||
| * frames per sec multiplied by FRAME_RATE_BASE | |||
| * for variable fps this is the precission, so if the timestamps | |||
| * can be specified in msec precssion then this is 1000*FRAME_RATE_BASE | |||
| * encoding: set by user | |||
| * encoding: MUST be set by user | |||
| * decoding: set by lavc. 0 or the frame_rate if available | |||
| */ | |||
| int frame_rate; | |||
| /** | |||
| * encoding: set by user. | |||
| * encoding: MUST be set by user. | |||
| * decoding: set by user, some codecs might override / change it during playback | |||
| */ | |||
| int width, height; | |||
| /** | |||
| * Obsolete, will be removed | |||
| */ | |||
| int aspect_ratio_info; | |||
| #define FF_ASPECT_SQUARE 1 | |||
| #define FF_ASPECT_4_3_625 2 | |||
| #define FF_ASPECT_4_3_525 3 | |||
| @@ -274,26 +374,14 @@ typedef struct AVCodecContext { | |||
| int frame_number; /* audio or video frame number */ | |||
| int real_pict_num; /* returns the real picture number of | |||
| previous encoded frame */ | |||
| /** | |||
| * 1 -> keyframe, 0-> not | |||
| * 1 -> keyframe, 0-> not (this if for audio only, for video, AVVideoFrame.key_frame should be used) | |||
| * encoding: set by lavc (for the outputed bitstream, not the input frame) | |||
| * decoding: set by lavc (for the decoded bitstream, not the displayed frame) | |||
| */ | |||
| int key_frame; | |||
| /** | |||
| * picture type of the previous en/decoded frame, see ?_TYPE below | |||
| * encoding: set by lavc (for the outputed bitstream, not the input frame) | |||
| * decoding: set by lavc (for the decoded bitstream, not the displayed frame) | |||
| */ | |||
| int pict_type; | |||
| /* FIXME: these should have FF_ */ | |||
| #define I_TYPE 1 // Intra | |||
| #define P_TYPE 2 // Predicted | |||
| #define B_TYPE 3 // Bi-dir predicted | |||
| #define S_TYPE 4 // S(GMC)-VOP MPEG4 | |||
| /** | |||
| * number of frames the decoded output will be delayed relative to | |||
| * the encoded input | |||
| @@ -301,25 +389,8 @@ typedef struct AVCodecContext { | |||
| * decoding: unused | |||
| */ | |||
| int delay; | |||
| /** | |||
| * mbskip_table[mb]=1 if MB didnt change, is only valid for I/P frames | |||
| * stride= mb_width = (width+15)>>4 (FIXME export stride?) | |||
| * encoding: unused | |||
| * decoding: set by lavc | |||
| */ | |||
| uint8_t *mbskip_table; | |||
| /* encoding parameters */ | |||
| /** | |||
| * quality (between 1 (good) and 31 (bad)) | |||
| * encoding: set by user if CODEC_FLAG_QSCALE is set otherwise set by lavc | |||
| * decoding: set by lavc | |||
| */ | |||
| int quality; /* quality of the previous encoded frame | |||
| this is allso used to set the quality in vbr mode | |||
| and the per frame quality in CODEC_FLAG_TYPE (second pass mode) */ | |||
| float qcompress; /* amount of qscale change between easy & hard scenes (0.0-1.0)*/ | |||
| float qblur; /* amount of qscale smoothing over time (0.0-1.0) */ | |||
| @@ -485,46 +556,21 @@ typedef struct AVCodecContext { | |||
| int error_resilience; | |||
| /** | |||
| * obsolete, just here to keep ABI compatible (should be removed perhaps, dunno) | |||
| */ | |||
| int *quant_store; | |||
| /** | |||
| * QP store stride | |||
| * encoding: unused | |||
| * decoding: set by lavc | |||
| */ | |||
| int qstride; | |||
| /** | |||
| * buffer, where the next picture should be decoded into | |||
| * called at the beginning of each frame to get a buffer for it. | |||
| * if pic.reference is set then the frame will be read later by lavc | |||
| * encoding: unused | |||
| * decoding: set by user in get_buffer_callback to a buffer into which the next part | |||
| * of the bitstream will be decoded, and set by lavc at end of frame to the | |||
| * next frame which needs to be displayed | |||
| * decoding: set by lavc, user can override | |||
| */ | |||
| uint8_t *dr_buffer[3]; | |||
| int (*get_buffer)(struct AVCodecContext *c, AVVideoFrame *pic); | |||
| /** | |||
| * stride of the luminance part of the dr buffer | |||
| * called to release buffers which where allocated with get_buffer. | |||
| * a released buffer can be reused in get_buffer() | |||
| * pic.data[*] must be set to NULL | |||
| * encoding: unused | |||
| * decoding: set by user | |||
| * decoding: set by lavc, user can override | |||
| */ | |||
| int dr_stride; | |||
| /** | |||
| * same behavior as dr_buffer, just for some private data of the user | |||
| * encoding: unused | |||
| * decoding: set by user in get_buffer_callback, and set by lavc at end of frame | |||
| */ | |||
| void *dr_opaque_frame; | |||
| /** | |||
| * called at the beginning of each frame to get a buffer for it | |||
| * encoding: unused | |||
| * decoding: set by user | |||
| */ | |||
| int (*get_buffer_callback)(struct AVCodecContext *c, int width, int height, int pict_type); | |||
| void (*release_buffer)(struct AVCodecContext *c, AVVideoFrame *pic); | |||
| /** | |||
| * is 1 if the decoded stream contains b frames, 0 otherwise | |||
| @@ -532,20 +578,6 @@ typedef struct AVCodecContext { | |||
| * decoding: set by lavc | |||
| */ | |||
| int has_b_frames; | |||
| /** | |||
| * stride of the chrominance part of the dr buffer | |||
| * encoding: unused | |||
| * decoding: set by user | |||
| */ | |||
| int dr_uvstride; | |||
| /** | |||
| * number of dr buffers | |||
| * encoding: unused | |||
| * decoding: set by user | |||
| */ | |||
| int dr_ip_buffer_count; | |||
| int block_align; /* used by some WAV based audio codecs */ | |||
| @@ -646,12 +678,6 @@ typedef struct AVCodecContext { | |||
| */ | |||
| float rc_initial_cplx; | |||
| /** | |||
| * Obsolete, will be removed | |||
| */ | |||
| int aspected_width; | |||
| int aspected_height; | |||
| /** | |||
| * dct algorithm, see FF_DCT_* below | |||
| * encoding: set by user | |||
| @@ -664,14 +690,6 @@ typedef struct AVCodecContext { | |||
| #define FF_DCT_MMX 3 | |||
| #define FF_DCT_MLIB 4 | |||
| #define FF_DCT_ALTIVEC 5 | |||
| /** | |||
| * presentation timestamp in micro seconds (time when frame should be shown to user) | |||
| * if 0 then the frame_rate will be used as reference | |||
| * encoding: set by user | |||
| * decoding; set by lavc | |||
| */ | |||
| long long int pts; | |||
| /** | |||
| * luminance masking (0-> disabled) | |||
| @@ -754,24 +772,6 @@ typedef struct AVCodecContext { | |||
| #define FF_EC_GUESS_MVS 1 | |||
| #define FF_EC_DEBLOCK 2 | |||
| /** | |||
| * QP table of the currently decoded frame | |||
| * encoding; unused | |||
| * decoding: set by lavc | |||
| */ | |||
| int8_t *current_qscale_table; | |||
| /** | |||
| * QP table of the currently displayed frame | |||
| * encoding; unused | |||
| * decoding: set by lavc | |||
| */ | |||
| int8_t *display_qscale_table; | |||
| /** | |||
| * force specific pict_type. | |||
| * encoding; set by user (I/P/B_TYPE) | |||
| * decoding: unused | |||
| */ | |||
| int force_type; | |||
| /** | |||
| * dsp_mask could be used to disable unwanted | |||
| * CPU features (i.e. MMX, SSE. ...) | |||
| @@ -780,14 +780,14 @@ typedef struct AVCodecContext { | |||
| /** | |||
| * bits per sample/pixel from the demuxer (needed for huffyuv) | |||
| * encoding; set by lavc | |||
| * encoding: set by lavc | |||
| * decoding: set by user | |||
| */ | |||
| int bits_per_sample; | |||
| /** | |||
| * prediction method (needed for huffyuv) | |||
| * encoding; set by user | |||
| * encoding: set by user | |||
| * decoding: unused | |||
| */ | |||
| int prediction_method; | |||
| @@ -801,6 +801,13 @@ typedef struct AVCodecContext { | |||
| * decoding: set by lavc. | |||
| */ | |||
| float aspect_ratio; | |||
| /** | |||
| * the picture in the bitstream | |||
| * encoding: set by lavc | |||
| * decoding: set by lavc | |||
| */ | |||
| AVVideoFrame *coded_picture; | |||
| } AVCodecContext; | |||
| typedef struct AVCodec { | |||
| @@ -928,6 +935,7 @@ void img_resample_close(ImgReSampleContext *s); | |||
| void avpicture_fill(AVPicture *picture, UINT8 *ptr, | |||
| int pix_fmt, int width, int height); | |||
| int avpicture_get_size(int pix_fmt, int width, int height); | |||
| void avcodec_get_chroma_sub_sample(int fmt, int *h_shift, int *v_shift); | |||
| /* convert among pixel formats */ | |||
| int img_convert(AVPicture *dst, int dst_pix_fmt, | |||
| @@ -957,12 +965,18 @@ AVCodec *avcodec_find_decoder(enum CodecID id); | |||
| AVCodec *avcodec_find_decoder_by_name(const char *name); | |||
| void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode); | |||
| void avcodec_get_context_defaults(AVCodecContext *s); | |||
| AVCodecContext *avcodec_alloc_context(void); | |||
| AVVideoFrame *avcodec_alloc_picture(void); | |||
| int avcodec_default_get_buffer(AVCodecContext *s, AVVideoFrame *pic); | |||
| void avcodec_default_release_buffer(AVCodecContext *s, AVVideoFrame *pic); | |||
| int avcodec_open(AVCodecContext *avctx, AVCodec *codec); | |||
| int avcodec_decode_audio(AVCodecContext *avctx, INT16 *samples, | |||
| int *frame_size_ptr, | |||
| UINT8 *buf, int buf_size); | |||
| int avcodec_decode_video(AVCodecContext *avctx, AVPicture *picture, | |||
| int avcodec_decode_video(AVCodecContext *avctx, AVVideoFrame *picture, | |||
| int *got_picture_ptr, | |||
| UINT8 *buf, int buf_size); | |||
| int avcodec_parse_frame(AVCodecContext *avctx, UINT8 **pdata, | |||
| @@ -971,7 +985,7 @@ int avcodec_parse_frame(AVCodecContext *avctx, UINT8 **pdata, | |||
| int avcodec_encode_audio(AVCodecContext *avctx, UINT8 *buf, int buf_size, | |||
| const short *samples); | |||
| int avcodec_encode_video(AVCodecContext *avctx, UINT8 *buf, int buf_size, | |||
| const AVPicture *pict); | |||
| const AVVideoFrame *pict); | |||
| int avcodec_close(AVCodecContext *avctx); | |||
| @@ -33,6 +33,7 @@ typedef struct DVVideoDecodeContext { | |||
| int sampling_411; /* 0 = 420, 1 = 411 */ | |||
| int width, height; | |||
| UINT8 *current_picture[3]; /* picture structure */ | |||
| AVVideoFrame picture; | |||
| int linesize[3]; | |||
| DCTELEM block[5*6][64] __align8; | |||
| UINT8 dv_zigzag[2][64]; | |||
| @@ -128,7 +129,7 @@ static int dvvideo_decode_init(AVCodecContext *avctx) | |||
| /* XXX: do it only for constant case */ | |||
| dv_build_unquantize_tables(s); | |||
| return 0; | |||
| } | |||
| @@ -499,7 +500,6 @@ static int dvvideo_decode_frame(AVCodecContext *avctx, | |||
| unsigned size; | |||
| UINT8 *buf_ptr; | |||
| const UINT16 *mb_pos_ptr; | |||
| AVPicture *picture; | |||
| /* parse id */ | |||
| init_get_bits(&s->gb, buf, buf_size); | |||
| @@ -561,45 +561,20 @@ static int dvvideo_decode_frame(AVCodecContext *avctx, | |||
| avctx->width = width; | |||
| avctx->height = height; | |||
| if (avctx->flags & CODEC_FLAG_DR1) | |||
| { | |||
| s->width = -1; | |||
| avctx->dr_buffer[0] = avctx->dr_buffer[1] = avctx->dr_buffer[2] = 0; | |||
| if(avctx->get_buffer_callback(avctx, width, height, I_TYPE) < 0 | |||
| && avctx->flags & CODEC_FLAG_DR1) { | |||
| fprintf(stderr, "get_buffer() failed\n"); | |||
| return -1; | |||
| } | |||
| s->picture.reference= 0; | |||
| if(avctx->get_buffer(avctx, &s->picture) < 0) { | |||
| fprintf(stderr, "get_buffer() failed\n"); | |||
| return -1; | |||
| } | |||
| /* (re)alloc picture if needed */ | |||
| if (s->width != width || s->height != height) { | |||
| if (!(avctx->flags & CODEC_FLAG_DR1)) | |||
| for(i=0;i<3;i++) { | |||
| if (avctx->dr_buffer[i] != s->current_picture[i]) | |||
| av_freep(&s->current_picture[i]); | |||
| avctx->dr_buffer[i] = 0; | |||
| } | |||
| for(i=0;i<3;i++) { | |||
| if (avctx->dr_buffer[i]) { | |||
| s->current_picture[i] = avctx->dr_buffer[i]; | |||
| s->linesize[i] = (i == 0) ? avctx->dr_stride : avctx->dr_uvstride; | |||
| } else { | |||
| size = width * height; | |||
| s->linesize[i] = width; | |||
| if (i >= 1) { | |||
| size >>= 2; | |||
| s->linesize[i] >>= s->sampling_411 ? 2 : 1; | |||
| } | |||
| s->current_picture[i] = av_malloc(size); | |||
| } | |||
| if (!s->current_picture[i]) | |||
| return -1; | |||
| } | |||
| s->width = width; | |||
| s->height = height; | |||
| for(i=0;i<3;i++) { | |||
| s->current_picture[i] = s->picture.data[i]; | |||
| s->linesize[i] = s->picture.linesize[i]; | |||
| if (!s->current_picture[i]) | |||
| return -1; | |||
| } | |||
| s->width = width; | |||
| s->height = height; | |||
| /* for each DIF segment */ | |||
| buf_ptr = buf; | |||
| @@ -620,12 +595,11 @@ static int dvvideo_decode_frame(AVCodecContext *avctx, | |||
| emms_c(); | |||
| /* return image */ | |||
| *data_size = sizeof(AVPicture); | |||
| picture = data; | |||
| for(i=0;i<3;i++) { | |||
| picture->data[i] = s->current_picture[i]; | |||
| picture->linesize[i] = s->linesize[i]; | |||
| } | |||
| *data_size = sizeof(AVVideoFrame); | |||
| *(AVVideoFrame*)data= s->picture; | |||
| avctx->release_buffer(avctx, &s->picture); | |||
| return packet_size; | |||
| } | |||
| @@ -633,10 +607,15 @@ static int dvvideo_decode_end(AVCodecContext *avctx) | |||
| { | |||
| DVVideoDecodeContext *s = avctx->priv_data; | |||
| int i; | |||
| if(avctx->get_buffer == avcodec_default_get_buffer){ | |||
| for(i=0; i<4; i++){ | |||
| av_freep(&s->picture.base[i]); | |||
| s->picture.data[i]= NULL; | |||
| } | |||
| av_freep(&s->picture.opaque); | |||
| } | |||
| for(i=0;i<3;i++) | |||
| if (avctx->dr_buffer[i] != s->current_picture[i]) | |||
| av_freep(&s->current_picture[i]); | |||
| return 0; | |||
| } | |||
| @@ -464,7 +464,7 @@ int score_sum=0; | |||
| s->mb_y= mb_y; | |||
| for(j=0; j<pred_count; j++){ | |||
| int score=0; | |||
| UINT8 *src= s->current_picture[0] + mb_x*16 + mb_y*16*s->linesize; | |||
| UINT8 *src= s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize; | |||
| s->motion_val[mot_index][0]= s->mv[0][0][0]= mv_predictor[j][0]; | |||
| s->motion_val[mot_index][1]= s->mv[0][0][1]= mv_predictor[j][1]; | |||
| @@ -556,8 +556,8 @@ static int is_intra_more_likely(MpegEncContext *s){ | |||
| if((j%skip_amount) != 0) continue; //skip a few to speed things up | |||
| if(s->pict_type==I_TYPE){ | |||
| UINT8 *mb_ptr = s->current_picture[0] + mb_x*16 + mb_y*16*s->linesize; | |||
| UINT8 *last_mb_ptr= s->last_picture [0] + mb_x*16 + mb_y*16*s->linesize; | |||
| UINT8 *mb_ptr = s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize; | |||
| UINT8 *last_mb_ptr= s->last_picture.data [0] + mb_x*16 + mb_y*16*s->linesize; | |||
| is_intra_likely += s->dsp.pix_abs16x16(last_mb_ptr, mb_ptr , s->linesize); | |||
| is_intra_likely -= s->dsp.pix_abs16x16(last_mb_ptr, last_mb_ptr+s->linesize*16, s->linesize); | |||
| @@ -802,9 +802,9 @@ void ff_error_resilience(MpegEncContext *s){ | |||
| if(s->mb_type[i]&MB_TYPE_INTRA) continue; //intra | |||
| // if(error&MV_ERROR) continue; //inter data damaged FIXME is this good? | |||
| dest_y = s->current_picture[0] + mb_x*16 + mb_y*16*s->linesize; | |||
| dest_cb= s->current_picture[1] + mb_x*8 + mb_y*8 *s->uvlinesize; | |||
| dest_cr= s->current_picture[2] + mb_x*8 + mb_y*8 *s->uvlinesize; | |||
| dest_y = s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize; | |||
| dest_cb= s->current_picture.data[1] + mb_x*8 + mb_y*8 *s->uvlinesize; | |||
| dest_cr= s->current_picture.data[2] + mb_x*8 + mb_y*8 *s->uvlinesize; | |||
| dc_ptr= &s->dc_val[0][mb_x*2+1 + (mb_y*2+1)*(s->mb_width*2+2)]; | |||
| for(n=0; n<4; n++){ | |||
| @@ -852,9 +852,9 @@ void ff_error_resilience(MpegEncContext *s){ | |||
| if(!(s->mb_type[i]&MB_TYPE_INTRA)) continue; //inter | |||
| if(!(error&AC_ERROR)) continue; //undamaged | |||
| dest_y = s->current_picture[0] + mb_x*16 + mb_y*16*s->linesize; | |||
| dest_cb= s->current_picture[1] + mb_x*8 + mb_y*8 *s->uvlinesize; | |||
| dest_cr= s->current_picture[2] + mb_x*8 + mb_y*8 *s->uvlinesize; | |||
| dest_y = s->current_picture.data[0] + mb_x*16 + mb_y*16*s->linesize; | |||
| dest_cb= s->current_picture.data[1] + mb_x*8 + mb_y*8 *s->uvlinesize; | |||
| dest_cr= s->current_picture.data[2] + mb_x*8 + mb_y*8 *s->uvlinesize; | |||
| put_dc(s, dest_y, dest_cb, dest_cr, mb_x, mb_y); | |||
| } | |||
| @@ -863,14 +863,14 @@ void ff_error_resilience(MpegEncContext *s){ | |||
| if(s->avctx->error_concealment&FF_EC_DEBLOCK){ | |||
| /* filter horizontal block boundaries */ | |||
| h_block_filter(s, s->current_picture[0], s->mb_width*2, s->mb_height*2, s->linesize , 1); | |||
| h_block_filter(s, s->current_picture[1], s->mb_width , s->mb_height , s->uvlinesize, 0); | |||
| h_block_filter(s, s->current_picture[2], s->mb_width , s->mb_height , s->uvlinesize, 0); | |||
| h_block_filter(s, s->current_picture.data[0], s->mb_width*2, s->mb_height*2, s->linesize , 1); | |||
| h_block_filter(s, s->current_picture.data[1], s->mb_width , s->mb_height , s->uvlinesize, 0); | |||
| h_block_filter(s, s->current_picture.data[2], s->mb_width , s->mb_height , s->uvlinesize, 0); | |||
| /* filter vertical block boundaries */ | |||
| v_block_filter(s, s->current_picture[0], s->mb_width*2, s->mb_height*2, s->linesize , 1); | |||
| v_block_filter(s, s->current_picture[1], s->mb_width , s->mb_height , s->uvlinesize, 0); | |||
| v_block_filter(s, s->current_picture[2], s->mb_width , s->mb_height , s->uvlinesize, 0); | |||
| v_block_filter(s, s->current_picture.data[0], s->mb_width*2, s->mb_height*2, s->linesize , 1); | |||
| v_block_filter(s, s->current_picture.data[1], s->mb_width , s->mb_height , s->uvlinesize, 0); | |||
| v_block_filter(s, s->current_picture.data[2], s->mb_width , s->mb_height , s->uvlinesize, 0); | |||
| } | |||
| /* clean a few tables */ | |||
| @@ -272,6 +272,7 @@ static inline int decide_ac_pred(MpegEncContext * s, DCTELEM block[6][64], int d | |||
| { | |||
| int score0=0, score1=0; | |||
| int i, n; | |||
| int8_t * const qscale_table= s->current_picture.qscale_table; | |||
| for(n=0; n<6; n++){ | |||
| INT16 *ac_val, *ac_val1; | |||
| @@ -282,7 +283,7 @@ static inline int decide_ac_pred(MpegEncContext * s, DCTELEM block[6][64], int d | |||
| const int xy= s->mb_x + s->mb_y*s->mb_width - s->mb_width; | |||
| /* top prediction */ | |||
| ac_val-= s->block_wrap[n]*16; | |||
| if(s->mb_y==0 || s->qscale == s->qscale_table[xy] || n==2 || n==3){ | |||
| if(s->mb_y==0 || s->qscale == qscale_table[xy] || n==2 || n==3){ | |||
| /* same qscale */ | |||
| for(i=1; i<8; i++){ | |||
| const int level= block[n][s->idct_permutation[i ]]; | |||
| @@ -296,7 +297,7 @@ static inline int decide_ac_pred(MpegEncContext * s, DCTELEM block[6][64], int d | |||
| for(i=1; i<8; i++){ | |||
| const int level= block[n][s->idct_permutation[i ]]; | |||
| score0+= ABS(level); | |||
| score1+= ABS(level - ROUNDED_DIV(ac_val[i + 8]*s->qscale_table[xy], s->qscale)); | |||
| score1+= ABS(level - ROUNDED_DIV(ac_val[i + 8]*qscale_table[xy], s->qscale)); | |||
| ac_val1[i ]= block[n][s->idct_permutation[i<<3]]; | |||
| ac_val1[i+8]= level; | |||
| } | |||
| @@ -305,7 +306,7 @@ static inline int decide_ac_pred(MpegEncContext * s, DCTELEM block[6][64], int d | |||
| const int xy= s->mb_x-1 + s->mb_y*s->mb_width; | |||
| /* left prediction */ | |||
| ac_val-= 16; | |||
| if(s->mb_x==0 || s->qscale == s->qscale_table[xy] || n==1 || n==3){ | |||
| if(s->mb_x==0 || s->qscale == qscale_table[xy] || n==1 || n==3){ | |||
| /* same qscale */ | |||
| for(i=1; i<8; i++){ | |||
| const int level= block[n][s->idct_permutation[i<<3]]; | |||
| @@ -319,7 +320,7 @@ static inline int decide_ac_pred(MpegEncContext * s, DCTELEM block[6][64], int d | |||
| for(i=1; i<8; i++){ | |||
| const int level= block[n][s->idct_permutation[i<<3]]; | |||
| score0+= ABS(level); | |||
| score1+= ABS(level - ROUNDED_DIV(ac_val[i]*s->qscale_table[xy], s->qscale)); | |||
| score1+= ABS(level - ROUNDED_DIV(ac_val[i]*qscale_table[xy], s->qscale)); | |||
| ac_val1[i ]= level; | |||
| ac_val1[i+8]= block[n][s->idct_permutation[i ]]; | |||
| } | |||
| @@ -335,14 +336,15 @@ static inline int decide_ac_pred(MpegEncContext * s, DCTELEM block[6][64], int d | |||
| */ | |||
| void ff_clean_h263_qscales(MpegEncContext *s){ | |||
| int i; | |||
| int8_t * const qscale_table= s->current_picture.qscale_table; | |||
| for(i=1; i<s->mb_num; i++){ | |||
| if(s->qscale_table[i] - s->qscale_table[i-1] >2) | |||
| s->qscale_table[i]= s->qscale_table[i-1]+2; | |||
| if(qscale_table[i] - qscale_table[i-1] >2) | |||
| qscale_table[i]= qscale_table[i-1]+2; | |||
| } | |||
| for(i=s->mb_num-2; i>=0; i--){ | |||
| if(s->qscale_table[i] - s->qscale_table[i+1] >2) | |||
| s->qscale_table[i]= s->qscale_table[i+1]+2; | |||
| if(qscale_table[i] - qscale_table[i+1] >2) | |||
| qscale_table[i]= qscale_table[i+1]+2; | |||
| } | |||
| } | |||
| @@ -351,11 +353,12 @@ void ff_clean_h263_qscales(MpegEncContext *s){ | |||
| */ | |||
| void ff_clean_mpeg4_qscales(MpegEncContext *s){ | |||
| int i; | |||
| int8_t * const qscale_table= s->current_picture.qscale_table; | |||
| ff_clean_h263_qscales(s); | |||
| for(i=1; i<s->mb_num; i++){ | |||
| if(s->qscale_table[i] != s->qscale_table[i-1] && (s->mb_type[i]&MB_TYPE_INTER4V)){ | |||
| if(qscale_table[i] != qscale_table[i-1] && (s->mb_type[i]&MB_TYPE_INTER4V)){ | |||
| s->mb_type[i]&= ~MB_TYPE_INTER4V; | |||
| s->mb_type[i]|= MB_TYPE_INTER; | |||
| } | |||
| @@ -367,21 +370,21 @@ void ff_clean_mpeg4_qscales(MpegEncContext *s){ | |||
| for the actual adaptive quantization */ | |||
| for(i=0; i<s->mb_num; i++){ | |||
| odd += s->qscale_table[i]&1; | |||
| odd += qscale_table[i]&1; | |||
| } | |||
| if(2*odd > s->mb_num) odd=1; | |||
| else odd=0; | |||
| for(i=0; i<s->mb_num; i++){ | |||
| if((s->qscale_table[i]&1) != odd) | |||
| s->qscale_table[i]++; | |||
| if(s->qscale_table[i] > 31) | |||
| s->qscale_table[i]= 31; | |||
| if((qscale_table[i]&1) != odd) | |||
| qscale_table[i]++; | |||
| if(qscale_table[i] > 31) | |||
| qscale_table[i]= 31; | |||
| } | |||
| for(i=1; i<s->mb_num; i++){ | |||
| if(s->qscale_table[i] != s->qscale_table[i-1] && (s->mb_type[i]&MB_TYPE_DIRECT)){ | |||
| if(qscale_table[i] != qscale_table[i-1] && (s->mb_type[i]&MB_TYPE_DIRECT)){ | |||
| s->mb_type[i]&= ~MB_TYPE_DIRECT; | |||
| s->mb_type[i]|= MB_TYPE_BIDIR; | |||
| } | |||
| @@ -427,7 +430,7 @@ void mpeg4_encode_mb(MpegEncContext * s, | |||
| assert(mb_type>=0); | |||
| /* nothing to do if this MB was skiped in the next P Frame */ | |||
| if(s->mbskip_table[s->mb_y * s->mb_width + s->mb_x]){ //FIXME avoid DCT & ... | |||
| if(s->next_picture.mbskip_table[s->mb_y * s->mb_width + s->mb_x]){ //FIXME avoid DCT & ... | |||
| s->skip_count++; | |||
| s->mv[0][0][0]= | |||
| s->mv[0][0][1]= | |||
| @@ -435,6 +438,8 @@ void mpeg4_encode_mb(MpegEncContext * s, | |||
| s->mv[1][0][1]= 0; | |||
| s->mv_dir= MV_DIR_FORWARD; //doesnt matter | |||
| s->qscale -= s->dquant; | |||
| // s->mb_skiped=1; | |||
| return; | |||
| } | |||
| @@ -451,6 +456,7 @@ void mpeg4_encode_mb(MpegEncContext * s, | |||
| s->skip_count++; | |||
| return; | |||
| } | |||
| put_bits(&s->pb, 1, 0); /* mb coded modb1=0 */ | |||
| put_bits(&s->pb, 1, cbp ? 0 : 1); /* modb2 */ //FIXME merge | |||
| put_bits(&s->pb, mb_type+1, 1); // this table is so simple that we dont need it :) | |||
| @@ -547,16 +553,17 @@ void mpeg4_encode_mb(MpegEncContext * s, | |||
| if(y+16 > s->height) y= s->height-16; | |||
| offset= x + y*s->linesize; | |||
| p_pic= s->new_picture[0] + offset; | |||
| p_pic= s->new_picture.data[0] + offset; | |||
| s->mb_skiped=1; | |||
| for(i=0; i<s->max_b_frames; i++){ | |||
| uint8_t *b_pic; | |||
| int diff; | |||
| Picture *pic= s->reordered_input_picture[i+1]; | |||
| if(s->coded_order[i+1].pict_type!=B_TYPE) break; | |||
| if(pic==NULL || pic->pict_type!=B_TYPE) break; | |||
| b_pic= s->coded_order[i+1].picture[0] + offset; | |||
| b_pic= pic->data[0] + offset + 16; //FIXME +16 | |||
| diff= s->dsp.pix_abs16x16(p_pic, b_pic, s->linesize); | |||
| if(diff>s->qscale*70){ //FIXME check that 70 is optimal | |||
| s->mb_skiped=0; | |||
| @@ -1493,8 +1500,8 @@ void ff_set_mpeg4_time(MpegEncContext * s, int picture_number){ | |||
| s->time_increment_bits = av_log2(s->time_increment_resolution - 1) + 1; | |||
| } | |||
| if(s->avctx->pts) | |||
| s->time= (s->avctx->pts*s->time_increment_resolution + 500*1000)/(1000*1000); | |||
| if(s->current_picture.pts) | |||
| s->time= (s->current_picture.pts*s->time_increment_resolution + 500*1000)/(1000*1000); | |||
| else | |||
| s->time= picture_number*(INT64)FRAME_RATE_BASE*s->time_increment_resolution/s->frame_rate; | |||
| time_div= s->time/s->time_increment_resolution; | |||
| @@ -1736,6 +1743,7 @@ void mpeg4_pred_ac(MpegEncContext * s, INT16 *block, int n, | |||
| { | |||
| int i; | |||
| INT16 *ac_val, *ac_val1; | |||
| int8_t * const qscale_table= s->current_picture.qscale_table; | |||
| /* find prediction */ | |||
| ac_val = s->ac_val[0][0] + s->block_index[n] * 16; | |||
| @@ -1746,7 +1754,7 @@ void mpeg4_pred_ac(MpegEncContext * s, INT16 *block, int n, | |||
| /* left prediction */ | |||
| ac_val -= 16; | |||
| if(s->mb_x==0 || s->qscale == s->qscale_table[xy] || n==1 || n==3){ | |||
| if(s->mb_x==0 || s->qscale == qscale_table[xy] || n==1 || n==3){ | |||
| /* same qscale */ | |||
| for(i=1;i<8;i++) { | |||
| block[s->idct_permutation[i<<3]] += ac_val[i]; | |||
| @@ -1754,7 +1762,7 @@ void mpeg4_pred_ac(MpegEncContext * s, INT16 *block, int n, | |||
| }else{ | |||
| /* different qscale, we must rescale */ | |||
| for(i=1;i<8;i++) { | |||
| block[s->idct_permutation[i<<3]] += ROUNDED_DIV(ac_val[i]*s->qscale_table[xy], s->qscale); | |||
| block[s->idct_permutation[i<<3]] += ROUNDED_DIV(ac_val[i]*qscale_table[xy], s->qscale); | |||
| } | |||
| } | |||
| } else { | |||
| @@ -1762,7 +1770,7 @@ void mpeg4_pred_ac(MpegEncContext * s, INT16 *block, int n, | |||
| /* top prediction */ | |||
| ac_val -= 16 * s->block_wrap[n]; | |||
| if(s->mb_y==0 || s->qscale == s->qscale_table[xy] || n==2 || n==3){ | |||
| if(s->mb_y==0 || s->qscale == qscale_table[xy] || n==2 || n==3){ | |||
| /* same qscale */ | |||
| for(i=1;i<8;i++) { | |||
| block[s->idct_permutation[i]] += ac_val[i + 8]; | |||
| @@ -1770,7 +1778,7 @@ void mpeg4_pred_ac(MpegEncContext * s, INT16 *block, int n, | |||
| }else{ | |||
| /* different qscale, we must rescale */ | |||
| for(i=1;i<8;i++) { | |||
| block[s->idct_permutation[i]] += ROUNDED_DIV(ac_val[i + 8]*s->qscale_table[xy], s->qscale); | |||
| block[s->idct_permutation[i]] += ROUNDED_DIV(ac_val[i + 8]*qscale_table[xy], s->qscale); | |||
| } | |||
| } | |||
| } | |||
| @@ -1790,6 +1798,7 @@ static void mpeg4_inv_pred_ac(MpegEncContext * s, INT16 *block, int n, | |||
| { | |||
| int i; | |||
| INT16 *ac_val; | |||
| int8_t * const qscale_table= s->current_picture.qscale_table; | |||
| /* find prediction */ | |||
| ac_val = s->ac_val[0][0] + s->block_index[n] * 16; | |||
| @@ -1798,7 +1807,7 @@ static void mpeg4_inv_pred_ac(MpegEncContext * s, INT16 *block, int n, | |||
| const int xy= s->mb_x-1 + s->mb_y*s->mb_width; | |||
| /* left prediction */ | |||
| ac_val -= 16; | |||
| if(s->mb_x==0 || s->qscale == s->qscale_table[xy] || n==1 || n==3){ | |||
| if(s->mb_x==0 || s->qscale == qscale_table[xy] || n==1 || n==3){ | |||
| /* same qscale */ | |||
| for(i=1;i<8;i++) { | |||
| block[s->idct_permutation[i<<3]] -= ac_val[i]; | |||
| @@ -1806,14 +1815,14 @@ static void mpeg4_inv_pred_ac(MpegEncContext * s, INT16 *block, int n, | |||
| }else{ | |||
| /* different qscale, we must rescale */ | |||
| for(i=1;i<8;i++) { | |||
| block[s->idct_permutation[i<<3]] -= ROUNDED_DIV(ac_val[i]*s->qscale_table[xy], s->qscale); | |||
| block[s->idct_permutation[i<<3]] -= ROUNDED_DIV(ac_val[i]*qscale_table[xy], s->qscale); | |||
| } | |||
| } | |||
| } else { | |||
| const int xy= s->mb_x + s->mb_y*s->mb_width - s->mb_width; | |||
| /* top prediction */ | |||
| ac_val -= 16 * s->block_wrap[n]; | |||
| if(s->mb_y==0 || s->qscale == s->qscale_table[xy] || n==2 || n==3){ | |||
| if(s->mb_y==0 || s->qscale == qscale_table[xy] || n==2 || n==3){ | |||
| /* same qscale */ | |||
| for(i=1;i<8;i++) { | |||
| block[s->idct_permutation[i]] -= ac_val[i + 8]; | |||
| @@ -1821,7 +1830,7 @@ static void mpeg4_inv_pred_ac(MpegEncContext * s, INT16 *block, int n, | |||
| }else{ | |||
| /* different qscale, we must rescale */ | |||
| for(i=1;i<8;i++) { | |||
| block[s->idct_permutation[i]] -= ROUNDED_DIV(ac_val[i + 8]*s->qscale_table[xy], s->qscale); | |||
| block[s->idct_permutation[i]] -= ROUNDED_DIV(ac_val[i + 8]*qscale_table[xy], s->qscale); | |||
| } | |||
| } | |||
| } | |||
| @@ -2532,7 +2541,7 @@ static int mpeg4_decode_partition_a(MpegEncContext *s){ | |||
| if(cbpc & 4) { | |||
| change_qscale(s, quant_tab[get_bits(&s->gb, 2)]); | |||
| } | |||
| s->qscale_table[xy]= s->qscale; | |||
| s->current_picture.qscale_table[xy]= s->qscale; | |||
| s->mbintra_table[xy]= 1; | |||
| for(i=0; i<6; i++){ | |||
| @@ -2704,7 +2713,7 @@ static int mpeg4_decode_partition_b(MpegEncContext *s, int mb_count){ | |||
| if(s->cbp_table[xy] & 8) { | |||
| change_qscale(s, quant_tab[get_bits(&s->gb, 2)]); | |||
| } | |||
| s->qscale_table[xy]= s->qscale; | |||
| s->current_picture.qscale_table[xy]= s->qscale; | |||
| for(i=0; i<6; i++){ | |||
| int dc_pred_dir; | |||
| @@ -2721,7 +2730,7 @@ static int mpeg4_decode_partition_b(MpegEncContext *s, int mb_count){ | |||
| s->pred_dir_table[xy]= dir | (ac_pred<<7); | |||
| s->error_status_table[xy]&= ~DC_ERROR; | |||
| }else if(s->mb_type[xy]&MB_TYPE_SKIPED){ | |||
| s->qscale_table[xy]= s->qscale; | |||
| s->current_picture.qscale_table[xy]= s->qscale; | |||
| s->cbp_table[xy]= 0; | |||
| }else{ | |||
| int cbpy = get_vlc2(&s->gb, cbpy_vlc.table, CBPY_VLC_BITS, 1); | |||
| @@ -2734,7 +2743,7 @@ static int mpeg4_decode_partition_b(MpegEncContext *s, int mb_count){ | |||
| if(s->cbp_table[xy] & 8) { | |||
| change_qscale(s, quant_tab[get_bits(&s->gb, 2)]); | |||
| } | |||
| s->qscale_table[xy]= s->qscale; | |||
| s->current_picture.qscale_table[xy]= s->qscale; | |||
| s->cbp_table[xy]&= 3; //remove dquant | |||
| s->cbp_table[xy]|= (cbpy^0xf)<<2; | |||
| @@ -2801,8 +2810,8 @@ static int mpeg4_decode_partitioned_mb(MpegEncContext *s, DCTELEM block[6][64]) | |||
| mb_type= s->mb_type[xy]; | |||
| cbp = s->cbp_table[xy]; | |||
| if(s->qscale_table[xy] != s->qscale){ | |||
| s->qscale= s->qscale_table[xy]; | |||
| if(s->current_picture.qscale_table[xy] != s->qscale){ | |||
| s->qscale= s->current_picture.qscale_table[xy]; | |||
| s->y_dc_scale= s->y_dc_scale_table[ s->qscale ]; | |||
| s->c_dc_scale= s->c_dc_scale_table[ s->qscale ]; | |||
| } | |||
| @@ -3054,7 +3063,7 @@ int ff_h263_decode_mb(MpegEncContext *s, | |||
| } | |||
| /* if we skipped it in the future P Frame than skip it now too */ | |||
| s->mb_skiped= s->mbskip_table[s->mb_y * s->mb_width + s->mb_x]; // Note, skiptab=0 if last was GMC | |||
| s->mb_skiped= s->next_picture.mbskip_table[s->mb_y * s->mb_width + s->mb_x]; // Note, skiptab=0 if last was GMC | |||
| if(s->mb_skiped){ | |||
| /* skip mb */ | |||
| @@ -3287,7 +3296,7 @@ end: | |||
| /* per-MB end of slice check */ | |||
| if(s->codec_id==CODEC_ID_MPEG4){ | |||
| if(mpeg4_is_resync(s)){ | |||
| if(s->pict_type==B_TYPE && s->mbskip_table[s->mb_y * s->mb_width + s->mb_x+1]) | |||
| if(s->pict_type==B_TYPE && s->next_picture.mbskip_table[s->mb_y * s->mb_width + s->mb_x+1]) | |||
| return SLICE_OK; | |||
| return SLICE_END; | |||
| } | |||
| @@ -4441,7 +4450,7 @@ static int decode_vop_header(MpegEncContext *s, GetBitContext *gb){ | |||
| - ROUNDED_DIV(s->last_non_b_time - s->pp_time, s->t_frame))*2; | |||
| } | |||
| s->avctx->pts= s->time*1000LL*1000LL / s->time_increment_resolution; | |||
| s->current_picture.pts= s->time*1000LL*1000LL / s->time_increment_resolution; | |||
| if(check_marker(gb, "before vop_coded")==0 && s->picture_number==0){ | |||
| printf("hmm, seems the headers arnt complete, trying to guess time_increment_bits\n"); | |||
| @@ -199,6 +199,7 @@ static int decode_slice(MpegEncContext *s){ | |||
| s->mv_dir = MV_DIR_FORWARD; | |||
| s->mv_type = MV_TYPE_16X16; | |||
| // s->mb_skiped = 0; | |||
| //printf("%d %d %06X\n", ret, get_bits_count(&s->gb), show_bits(&s->gb, 24)); | |||
| ret= s->decode_mb(s, s->block); | |||
| @@ -347,7 +348,7 @@ static int h263_decode_frame(AVCodecContext *avctx, | |||
| { | |||
| MpegEncContext *s = avctx->priv_data; | |||
| int ret,i; | |||
| AVPicture *pict = data; | |||
| AVVideoFrame *pict = data; | |||
| float new_aspect; | |||
| #ifdef PRINT_FRAME_TIME | |||
| @@ -357,7 +358,6 @@ uint64_t time= rdtsc(); | |||
| printf("*****frame %d size=%d\n", avctx->frame_number, buf_size); | |||
| printf("bytes=%x %x %x %x\n", buf[0], buf[1], buf[2], buf[3]); | |||
| #endif | |||
| s->flags= avctx->flags; | |||
| *data_size = 0; | |||
| @@ -523,8 +523,9 @@ retry: | |||
| return -1; | |||
| } | |||
| s->avctx->key_frame = (s->pict_type == I_TYPE); | |||
| s->avctx->pict_type = s->pict_type; | |||
| // 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 dont have reference frames */ | |||
| if(s->num_available_buffers<2 && s->pict_type==B_TYPE) return get_consumed_bytes(s, buf_size); | |||
| @@ -580,7 +581,9 @@ retry: | |||
| } | |||
| if (s->h263_msmpeg4 && s->msmpeg4_version<4 && s->pict_type==I_TYPE) | |||
| if(msmpeg4_decode_ext_header(s, buf_size) < 0) return -1; | |||
| if(msmpeg4_decode_ext_header(s, buf_size) < 0){ | |||
| s->error_status_table[s->mb_num-1]= AC_ERROR|DC_ERROR|MV_ERROR; | |||
| } | |||
| /* divx 5.01+ bistream reorder stuff */ | |||
| if(s->codec_id==CODEC_ID_MPEG4 && s->bitstream_buffer_size==0 && s->divx_version>=500){ | |||
| @@ -644,7 +647,7 @@ retry: | |||
| int y= mb_y*16 + 8; | |||
| for(mb_x=0; mb_x<s->mb_width; mb_x++){ | |||
| int x= mb_x*16 + 8; | |||
| uint8_t *ptr= s->last_picture[0]; | |||
| uint8_t *ptr= s->last_picture.data[0]; | |||
| int xy= 1 + mb_x*2 + (mb_y*2 + 1)*(s->mb_width*2 + 2); | |||
| int mx= (s->motion_val[xy][0]>>1) + x; | |||
| int my= (s->motion_val[xy][1]>>1) + y; | |||
| @@ -669,21 +672,12 @@ retry: | |||
| } | |||
| } | |||
| #endif | |||
| #endif | |||
| if(s->pict_type==B_TYPE || (!s->has_b_frames)){ | |||
| pict->data[0] = s->current_picture[0]; | |||
| pict->data[1] = s->current_picture[1]; | |||
| pict->data[2] = s->current_picture[2]; | |||
| *pict= *(AVVideoFrame*)&s->current_picture; | |||
| } else { | |||
| pict->data[0] = s->last_picture[0]; | |||
| pict->data[1] = s->last_picture[1]; | |||
| pict->data[2] = s->last_picture[2]; | |||
| *pict= *(AVVideoFrame*)&s->last_picture; | |||
| } | |||
| pict->linesize[0] = s->linesize; | |||
| pict->linesize[1] = s->uvlinesize; | |||
| pict->linesize[2] = s->uvlinesize; | |||
| avctx->quality = s->qscale; | |||
| /* Return the Picture timestamp as the frame number */ | |||
| /* we substract 1 because it is added on utils.c */ | |||
| @@ -692,7 +686,7 @@ retry: | |||
| /* dont output the last pic after seeking | |||
| note we allready added +1 for the current pix in MPV_frame_end(s) */ | |||
| if(s->num_available_buffers>=2 || (!s->has_b_frames)) | |||
| *data_size = sizeof(AVPicture); | |||
| *data_size = sizeof(AVVideoFrame); | |||
| #ifdef PRINT_FRAME_TIME | |||
| printf("%Ld\n", rdtsc()-time); | |||
| #endif | |||
| @@ -30,7 +30,7 @@ | |||
| #endif | |||
| #define VLC_BITS 11 | |||
| typedef enum Predictor{ | |||
| LEFT= 0, | |||
| PLANE, | |||
| @@ -52,13 +52,12 @@ typedef struct HYuvContext{ | |||
| int flags; | |||
| int picture_number; | |||
| int last_slice_end; | |||
| int linesize[3]; | |||
| uint8_t __align8 temp[3][2500]; | |||
| uint64_t stats[3][256]; | |||
| uint8_t len[3][256]; | |||
| uint32_t bits[3][256]; | |||
| VLC vlc[3]; | |||
| uint8_t __align8 *picture[3]; | |||
| AVVideoFrame picture; | |||
| uint8_t __align8 bitstream_buffer[1024*1024*3]; //FIXME dynamic alloc or some other solution | |||
| DSPContext dsp; | |||
| }HYuvContext; | |||
| @@ -324,7 +323,7 @@ static int read_old_huffman_tables(HYuvContext *s){ | |||
| static int decode_init(AVCodecContext *avctx) | |||
| { | |||
| HYuvContext *s = avctx->priv_data; | |||
| int width, height, y_size, c_size, stride; | |||
| int width, height; | |||
| s->avctx= avctx; | |||
| s->flags= avctx->flags; | |||
| @@ -333,6 +332,8 @@ static int decode_init(AVCodecContext *avctx) | |||
| width= s->width= avctx->width; | |||
| height= s->height= avctx->height; | |||
| avctx->coded_picture= &s->picture; | |||
| s->bgr32=1; | |||
| assert(width && height); | |||
| //if(avctx->extradata) | |||
| @@ -388,52 +389,27 @@ s->bgr32=1; | |||
| s->interlaced= height > 288; | |||
| c_size= 0; | |||
| switch(s->bitstream_bpp){ | |||
| case 12: | |||
| avctx->pix_fmt = PIX_FMT_YUV420P; | |||
| stride= (width+15)&~15; | |||
| c_size= height*stride/4; | |||
| break; | |||
| case 16: | |||
| if(s->yuy2){ | |||
| avctx->pix_fmt = PIX_FMT_YUV422; | |||
| stride= (width*2+15)&~15; | |||
| }else{ | |||
| avctx->pix_fmt = PIX_FMT_YUV422P; | |||
| stride= (width+15)&~15; | |||
| c_size= height*stride/2; | |||
| } | |||
| break; | |||
| case 24: | |||
| case 32: | |||
| if(s->bgr32){ | |||
| avctx->pix_fmt = PIX_FMT_BGRA32; | |||
| stride= (width*4+15)&~15; | |||
| }else{ | |||
| avctx->pix_fmt = PIX_FMT_BGR24; | |||
| stride= (width*3+15)&~15; | |||
| } | |||
| break; | |||
| default: | |||
| assert(0); | |||
| stride=0; //gcc fix | |||
| } | |||
| y_size= height*stride; | |||
| if(!(avctx->flags&CODEC_FLAG_DR1)){ | |||
| s->linesize[0]= stride; | |||
| s->picture[0]= av_mallocz(y_size); | |||
| if(c_size){ | |||
| s->picture[1]= av_mallocz(c_size); | |||
| s->picture[2]= av_mallocz(c_size); | |||
| s->linesize[1]= s->linesize[2]= stride/2; | |||
| memset(s->picture[1], 128, c_size); | |||
| memset(s->picture[2], 128, c_size); | |||
| } | |||
| } | |||
| // printf("pred:%d bpp:%d hbpp:%d il:%d\n", s->predictor, s->bitstream_bpp, avctx->bits_per_sample, s->interlaced); | |||
| @@ -484,6 +460,10 @@ static int encode_init(AVCodecContext *avctx) | |||
| avctx->stats_out= av_mallocz(1024*10); | |||
| s->version=2; | |||
| avctx->coded_picture= &s->picture; | |||
| s->picture.pict_type= I_TYPE; | |||
| s->picture.key_frame= 1; | |||
| switch(avctx->pix_fmt){ | |||
| case PIX_FMT_YUV420P: | |||
| if(avctx->strict_std_compliance>=0){ | |||
| @@ -674,12 +654,12 @@ static void draw_slice(HYuvContext *s, int y){ | |||
| cy= y; | |||
| } | |||
| src_ptr[0] = s->picture[0] + s->linesize[0]*y; | |||
| src_ptr[1] = s->picture[1] + s->linesize[1]*cy; | |||
| src_ptr[2] = s->picture[2] + s->linesize[2]*cy; | |||
| src_ptr[0] = s->picture.data[0] + s->picture.linesize[0]*y; | |||
| src_ptr[1] = s->picture.data[1] + s->picture.linesize[1]*cy; | |||
| src_ptr[2] = s->picture.data[2] + s->picture.linesize[2]*cy; | |||
| emms_c(); | |||
| s->avctx->draw_horiz_band(s->avctx, src_ptr, s->linesize[0], y, s->width, h); | |||
| s->avctx->draw_horiz_band(s->avctx, src_ptr, s->picture.linesize[0], y, s->width, h); | |||
| s->last_slice_end= y + h; | |||
| } | |||
| @@ -690,9 +670,9 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8 | |||
| const int width2= s->width>>1; | |||
| const int height= s->height; | |||
| int fake_ystride, fake_ustride, fake_vstride; | |||
| int i; | |||
| AVVideoFrame * const p= &s->picture; | |||
| AVPicture *picture = data; | |||
| AVVideoFrame *picture = data; | |||
| *data_size = 0; | |||
| @@ -704,22 +684,15 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8 | |||
| init_get_bits(&s->gb, s->bitstream_buffer, buf_size); | |||
| if(avctx->flags&CODEC_FLAG_DR1){ | |||
| if(avctx->get_buffer_callback(avctx, s->width, s->height, I_TYPE) < 0){ | |||
| fprintf(stderr, "get_buffer() failed\n"); | |||
| return -1; | |||
| } | |||
| s->linesize[0]= avctx->dr_stride; | |||
| s->linesize[1]= | |||
| s->linesize[2]= avctx->dr_uvstride; | |||
| for(i=0; i<3;i++) | |||
| s->picture[i]= avctx->dr_buffer[i]; | |||
| p->reference= 0; | |||
| if(avctx->get_buffer(avctx, p) < 0){ | |||
| fprintf(stderr, "get_buffer() failed\n"); | |||
| return -1; | |||
| } | |||
| fake_ystride= s->interlaced ? s->linesize[0]*2 : s->linesize[0]; | |||
| fake_ustride= s->interlaced ? s->linesize[1]*2 : s->linesize[1]; | |||
| fake_vstride= s->interlaced ? s->linesize[2]*2 : s->linesize[2]; | |||
| fake_ystride= s->interlaced ? p->linesize[0]*2 : p->linesize[0]; | |||
| fake_ustride= s->interlaced ? p->linesize[1]*2 : p->linesize[1]; | |||
| fake_vstride= s->interlaced ? p->linesize[2]*2 : p->linesize[2]; | |||
| s->last_slice_end= 0; | |||
| @@ -729,28 +702,28 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8 | |||
| int lefttopy, lefttopu, lefttopv; | |||
| if(s->yuy2){ | |||
| s->picture[0][3]= get_bits(&s->gb, 8); | |||
| s->picture[0][2]= get_bits(&s->gb, 8); | |||
| s->picture[0][1]= get_bits(&s->gb, 8); | |||
| s->picture[0][0]= get_bits(&s->gb, 8); | |||
| p->data[0][3]= get_bits(&s->gb, 8); | |||
| p->data[0][2]= get_bits(&s->gb, 8); | |||
| p->data[0][1]= get_bits(&s->gb, 8); | |||
| p->data[0][0]= get_bits(&s->gb, 8); | |||
| fprintf(stderr, "YUY2 output isnt implemenetd yet\n"); | |||
| return -1; | |||
| }else{ | |||
| leftv= s->picture[2][0]= get_bits(&s->gb, 8); | |||
| lefty= s->picture[0][1]= get_bits(&s->gb, 8); | |||
| leftu= s->picture[1][0]= get_bits(&s->gb, 8); | |||
| s->picture[0][0]= get_bits(&s->gb, 8); | |||
| leftv= p->data[2][0]= get_bits(&s->gb, 8); | |||
| lefty= p->data[0][1]= get_bits(&s->gb, 8); | |||
| leftu= p->data[1][0]= get_bits(&s->gb, 8); | |||
| p->data[0][0]= get_bits(&s->gb, 8); | |||
| switch(s->predictor){ | |||
| case LEFT: | |||
| case PLANE: | |||
| decode_422_bitstream(s, width-2); | |||
| lefty= add_left_prediction(s->picture[0] + 2, s->temp[0], width-2, lefty); | |||
| lefty= add_left_prediction(p->data[0] + 2, s->temp[0], width-2, lefty); | |||
| if(!(s->flags&CODEC_FLAG_GRAY)){ | |||
| leftu= add_left_prediction(s->picture[1] + 1, s->temp[1], width2-1, leftu); | |||
| leftv= add_left_prediction(s->picture[2] + 1, s->temp[2], width2-1, leftv); | |||
| leftu= add_left_prediction(p->data[1] + 1, s->temp[1], width2-1, leftu); | |||
| leftv= add_left_prediction(p->data[2] + 1, s->temp[2], width2-1, leftv); | |||
| } | |||
| for(cy=y=1; y<s->height; y++,cy++){ | |||
| @@ -759,7 +732,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8 | |||
| if(s->bitstream_bpp==12){ | |||
| decode_gray_bitstream(s, width); | |||
| ydst= s->picture[0] + s->linesize[0]*y; | |||
| ydst= p->data[0] + p->linesize[0]*y; | |||
| lefty= add_left_prediction(ydst, s->temp[0], width, lefty); | |||
| if(s->predictor == PLANE){ | |||
| @@ -772,12 +745,11 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8 | |||
| draw_slice(s, y); | |||
| ydst= s->picture[0] + s->linesize[0]*y; | |||
| udst= s->picture[1] + s->linesize[1]*cy; | |||
| vdst= s->picture[2] + s->linesize[2]*cy; | |||
| ydst= p->data[0] + p->linesize[0]*y; | |||
| udst= p->data[1] + p->linesize[1]*cy; | |||
| vdst= p->data[2] + p->linesize[2]*cy; | |||
| decode_422_bitstream(s, width); | |||
| lefty= add_left_prediction(ydst, s->temp[0], width, lefty); | |||
| if(!(s->flags&CODEC_FLAG_GRAY)){ | |||
| leftu= add_left_prediction(udst, s->temp[1], width2, leftu); | |||
| @@ -799,10 +771,10 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8 | |||
| case MEDIAN: | |||
| /* first line except first 2 pixels is left predicted */ | |||
| decode_422_bitstream(s, width-2); | |||
| lefty= add_left_prediction(s->picture[0] + 2, s->temp[0], width-2, lefty); | |||
| lefty= add_left_prediction(p->data[0] + 2, s->temp[0], width-2, lefty); | |||
| if(!(s->flags&CODEC_FLAG_GRAY)){ | |||
| leftu= add_left_prediction(s->picture[1] + 1, s->temp[1], width2-1, leftu); | |||
| leftv= add_left_prediction(s->picture[2] + 1, s->temp[2], width2-1, leftv); | |||
| leftu= add_left_prediction(p->data[1] + 1, s->temp[1], width2-1, leftu); | |||
| leftv= add_left_prediction(p->data[2] + 1, s->temp[2], width2-1, leftv); | |||
| } | |||
| cy=y=1; | |||
| @@ -810,31 +782,31 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8 | |||
| /* second line is left predicted for interlaced case */ | |||
| if(s->interlaced){ | |||
| decode_422_bitstream(s, width); | |||
| lefty= add_left_prediction(s->picture[0] + s->linesize[0], s->temp[0], width, lefty); | |||
| lefty= add_left_prediction(p->data[0] + p->linesize[0], s->temp[0], width, lefty); | |||
| if(!(s->flags&CODEC_FLAG_GRAY)){ | |||
| leftu= add_left_prediction(s->picture[1] + s->linesize[2], s->temp[1], width2, leftu); | |||
| leftv= add_left_prediction(s->picture[2] + s->linesize[1], s->temp[2], width2, leftv); | |||
| leftu= add_left_prediction(p->data[1] + p->linesize[2], s->temp[1], width2, leftu); | |||
| leftv= add_left_prediction(p->data[2] + p->linesize[1], s->temp[2], width2, leftv); | |||
| } | |||
| y++; cy++; | |||
| } | |||
| /* next 4 pixels are left predicted too */ | |||
| decode_422_bitstream(s, 4); | |||
| lefty= add_left_prediction(s->picture[0] + fake_ystride, s->temp[0], 4, lefty); | |||
| lefty= add_left_prediction(p->data[0] + fake_ystride, s->temp[0], 4, lefty); | |||
| if(!(s->flags&CODEC_FLAG_GRAY)){ | |||
| leftu= add_left_prediction(s->picture[1] + fake_ustride, s->temp[1], 2, leftu); | |||
| leftv= add_left_prediction(s->picture[2] + fake_vstride, s->temp[2], 2, leftv); | |||
| leftu= add_left_prediction(p->data[1] + fake_ustride, s->temp[1], 2, leftu); | |||
| leftv= add_left_prediction(p->data[2] + fake_vstride, s->temp[2], 2, leftv); | |||
| } | |||
| /* next line except the first 4 pixels is median predicted */ | |||
| lefttopy= s->picture[0][3]; | |||
| lefttopy= p->data[0][3]; | |||
| decode_422_bitstream(s, width-4); | |||
| add_median_prediction(s->picture[0] + fake_ystride+4, s->picture[0]+4, s->temp[0], width-4, &lefty, &lefttopy); | |||
| add_median_prediction(p->data[0] + fake_ystride+4, p->data[0]+4, s->temp[0], width-4, &lefty, &lefttopy); | |||
| if(!(s->flags&CODEC_FLAG_GRAY)){ | |||
| lefttopu= s->picture[1][1]; | |||
| lefttopv= s->picture[2][1]; | |||
| add_median_prediction(s->picture[1] + fake_ustride+2, s->picture[1]+2, s->temp[1], width2-2, &leftu, &lefttopu); | |||
| add_median_prediction(s->picture[2] + fake_vstride+2, s->picture[2]+2, s->temp[2], width2-2, &leftv, &lefttopv); | |||
| lefttopu= p->data[1][1]; | |||
| lefttopv= p->data[2][1]; | |||
| add_median_prediction(p->data[1] + fake_ustride+2, p->data[1]+2, s->temp[1], width2-2, &leftu, &lefttopu); | |||
| add_median_prediction(p->data[2] + fake_vstride+2, p->data[2]+2, s->temp[2], width2-2, &leftv, &lefttopv); | |||
| } | |||
| y++; cy++; | |||
| @@ -844,7 +816,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8 | |||
| if(s->bitstream_bpp==12){ | |||
| while(2*cy > y){ | |||
| decode_gray_bitstream(s, width); | |||
| ydst= s->picture[0] + s->linesize[0]*y; | |||
| ydst= p->data[0] + p->linesize[0]*y; | |||
| add_median_prediction(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy); | |||
| y++; | |||
| } | |||
| @@ -854,9 +826,9 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8 | |||
| decode_422_bitstream(s, width); | |||
| ydst= s->picture[0] + s->linesize[0]*y; | |||
| udst= s->picture[1] + s->linesize[1]*cy; | |||
| vdst= s->picture[2] + s->linesize[2]*cy; | |||
| ydst= p->data[0] + p->linesize[0]*y; | |||
| udst= p->data[1] + p->linesize[1]*cy; | |||
| vdst= p->data[2] + p->linesize[2]*cy; | |||
| add_median_prediction(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy); | |||
| if(!(s->flags&CODEC_FLAG_GRAY)){ | |||
| @@ -872,17 +844,17 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8 | |||
| }else{ | |||
| int y; | |||
| int leftr, leftg, leftb; | |||
| const int last_line= (height-1)*s->linesize[0]; | |||
| const int last_line= (height-1)*p->linesize[0]; | |||
| if(s->bitstream_bpp==32){ | |||
| s->picture[0][last_line+3]= get_bits(&s->gb, 8); | |||
| leftr= s->picture[0][last_line+2]= get_bits(&s->gb, 8); | |||
| leftg= s->picture[0][last_line+1]= get_bits(&s->gb, 8); | |||
| leftb= s->picture[0][last_line+0]= get_bits(&s->gb, 8); | |||
| p->data[0][last_line+3]= get_bits(&s->gb, 8); | |||
| leftr= p->data[0][last_line+2]= get_bits(&s->gb, 8); | |||
| leftg= p->data[0][last_line+1]= get_bits(&s->gb, 8); | |||
| leftb= p->data[0][last_line+0]= get_bits(&s->gb, 8); | |||
| }else{ | |||
| leftr= s->picture[0][last_line+2]= get_bits(&s->gb, 8); | |||
| leftg= s->picture[0][last_line+1]= get_bits(&s->gb, 8); | |||
| leftb= s->picture[0][last_line+0]= get_bits(&s->gb, 8); | |||
| leftr= p->data[0][last_line+2]= get_bits(&s->gb, 8); | |||
| leftg= p->data[0][last_line+1]= get_bits(&s->gb, 8); | |||
| leftb= p->data[0][last_line+0]= get_bits(&s->gb, 8); | |||
| skip_bits(&s->gb, 8); | |||
| } | |||
| @@ -891,16 +863,16 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8 | |||
| case LEFT: | |||
| case PLANE: | |||
| decode_bgr_bitstream(s, width-1); | |||
| add_left_prediction_bgr32(s->picture[0] + last_line+4, s->temp[0], width-1, &leftr, &leftg, &leftb); | |||
| add_left_prediction_bgr32(p->data[0] + last_line+4, s->temp[0], width-1, &leftr, &leftg, &leftb); | |||
| for(y=s->height-2; y>=0; y--){ //yes its stored upside down | |||
| decode_bgr_bitstream(s, width); | |||
| add_left_prediction_bgr32(s->picture[0] + s->linesize[0]*y, s->temp[0], width, &leftr, &leftg, &leftb); | |||
| add_left_prediction_bgr32(p->data[0] + p->linesize[0]*y, s->temp[0], width, &leftr, &leftg, &leftb); | |||
| if(s->predictor == PLANE){ | |||
| if((y&s->interlaced)==0){ | |||
| s->dsp.add_bytes(s->picture[0] + s->linesize[0]*y, | |||
| s->picture[0] + s->linesize[0]*y + fake_ystride, fake_ystride); | |||
| s->dsp.add_bytes(p->data[0] + p->linesize[0]*y, | |||
| p->data[0] + p->linesize[0]*y + fake_ystride, fake_ystride); | |||
| } | |||
| } | |||
| } | |||
| @@ -917,12 +889,11 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8 | |||
| } | |||
| emms_c(); | |||
| for(i=0;i<3;i++) { | |||
| picture->data[i] = s->picture[i]; | |||
| picture->linesize[i]= s->linesize[i]; | |||
| } | |||
| *picture= *p; | |||
| avctx->release_buffer(avctx, p); | |||
| *data_size = sizeof(AVPicture); | |||
| *data_size = sizeof(AVVideoFrame); | |||
| return (get_bits_count(&s->gb)+7)>>3; | |||
| } | |||
| @@ -933,44 +904,47 @@ static int decode_end(AVCodecContext *avctx) | |||
| int i; | |||
| for(i=0; i<3; i++){ | |||
| if(!(avctx->flags&CODEC_FLAG_DR1)) | |||
| av_freep(&s->picture[i]); | |||
| free_vlc(&s->vlc[i]); | |||
| } | |||
| if(avctx->get_buffer == avcodec_default_get_buffer){ | |||
| for(i=0; i<4; i++){ | |||
| av_freep(&s->picture.base[i]); | |||
| s->picture.data[i]= NULL; | |||
| } | |||
| av_freep(&s->picture.opaque); | |||
| } | |||
| return 0; | |||
| } | |||
| static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){ | |||
| HYuvContext *s = avctx->priv_data; | |||
| AVPicture *pict = data; | |||
| AVVideoFrame *pict = data; | |||
| const int width= s->width; | |||
| const int width2= s->width>>1; | |||
| const int height= s->height; | |||
| const int fake_ystride= s->interlaced ? pict->linesize[0]*2 : pict->linesize[0]; | |||
| const int fake_ustride= s->interlaced ? pict->linesize[1]*2 : pict->linesize[1]; | |||
| const int fake_vstride= s->interlaced ? pict->linesize[2]*2 : pict->linesize[2]; | |||
| AVVideoFrame * const p= &s->picture; | |||
| int i, size; | |||
| init_put_bits(&s->pb, buf, buf_size, NULL, NULL); | |||
| for(i=0; i<3; i++){ | |||
| s->picture[i]= pict->data[i]; | |||
| s->linesize[i]= pict->linesize[i]; | |||
| } | |||
| *p = *pict; | |||
| if(avctx->pix_fmt == PIX_FMT_YUV422P || avctx->pix_fmt == PIX_FMT_YUV420P){ | |||
| int lefty, leftu, leftv, y, cy; | |||
| put_bits(&s->pb, 8, leftv= s->picture[2][0]); | |||
| put_bits(&s->pb, 8, lefty= s->picture[0][1]); | |||
| put_bits(&s->pb, 8, leftu= s->picture[1][0]); | |||
| put_bits(&s->pb, 8, s->picture[0][0]); | |||
| put_bits(&s->pb, 8, leftv= p->data[2][0]); | |||
| put_bits(&s->pb, 8, lefty= p->data[0][1]); | |||
| put_bits(&s->pb, 8, leftu= p->data[1][0]); | |||
| put_bits(&s->pb, 8, p->data[0][0]); | |||
| lefty= sub_left_prediction(s, s->temp[0], s->picture[0]+2, width-2 , lefty); | |||
| leftu= sub_left_prediction(s, s->temp[1], s->picture[1]+1, width2-1, leftu); | |||
| leftv= sub_left_prediction(s, s->temp[2], s->picture[2]+1, width2-1, leftv); | |||
| lefty= sub_left_prediction(s, s->temp[0], p->data[0]+2, width-2 , lefty); | |||
| leftu= sub_left_prediction(s, s->temp[1], p->data[1]+1, width2-1, leftu); | |||
| leftv= sub_left_prediction(s, s->temp[2], p->data[2]+1, width2-1, leftv); | |||
| encode_422_bitstream(s, width-2); | |||
| @@ -978,26 +952,26 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, | |||
| int lefttopy, lefttopu, lefttopv; | |||
| cy=y=1; | |||
| if(s->interlaced){ | |||
| lefty= sub_left_prediction(s, s->temp[0], s->picture[0]+s->linesize[0], width , lefty); | |||
| leftu= sub_left_prediction(s, s->temp[1], s->picture[1]+s->linesize[1], width2, leftu); | |||
| leftv= sub_left_prediction(s, s->temp[2], s->picture[2]+s->linesize[2], width2, leftv); | |||
| lefty= sub_left_prediction(s, s->temp[0], p->data[0]+p->linesize[0], width , lefty); | |||
| leftu= sub_left_prediction(s, s->temp[1], p->data[1]+p->linesize[1], width2, leftu); | |||
| leftv= sub_left_prediction(s, s->temp[2], p->data[2]+p->linesize[2], width2, leftv); | |||
| encode_422_bitstream(s, width); | |||
| y++; cy++; | |||
| } | |||
| lefty= sub_left_prediction(s, s->temp[0], s->picture[0]+fake_ystride, 4, lefty); | |||
| leftu= sub_left_prediction(s, s->temp[1], s->picture[1]+fake_ystride, 2, leftu); | |||
| leftv= sub_left_prediction(s, s->temp[2], s->picture[2]+fake_ystride, 2, leftv); | |||
| lefty= sub_left_prediction(s, s->temp[0], p->data[0]+fake_ystride, 4, lefty); | |||
| leftu= sub_left_prediction(s, s->temp[1], p->data[1]+fake_ystride, 2, leftu); | |||
| leftv= sub_left_prediction(s, s->temp[2], p->data[2]+fake_ystride, 2, leftv); | |||
| encode_422_bitstream(s, 4); | |||
| lefttopy= s->picture[0][3]; | |||
| lefttopu= s->picture[1][1]; | |||
| lefttopv= s->picture[2][1]; | |||
| sub_median_prediction(s->temp[0], s->picture[0]+4, s->picture[0] + fake_ystride+4, width-4 , &lefty, &lefttopy); | |||
| sub_median_prediction(s->temp[1], s->picture[1]+2, s->picture[1] + fake_ustride+2, width2-2, &leftu, &lefttopu); | |||
| sub_median_prediction(s->temp[2], s->picture[2]+2, s->picture[2] + fake_vstride+2, width2-2, &leftv, &lefttopv); | |||
| lefttopy= p->data[0][3]; | |||
| lefttopu= p->data[1][1]; | |||
| lefttopv= p->data[2][1]; | |||
| sub_median_prediction(s->temp[0], p->data[0]+4, p->data[0] + fake_ystride+4, width-4 , &lefty, &lefttopy); | |||
| sub_median_prediction(s->temp[1], p->data[1]+2, p->data[1] + fake_ustride+2, width2-2, &leftu, &lefttopu); | |||
| sub_median_prediction(s->temp[2], p->data[2]+2, p->data[2] + fake_vstride+2, width2-2, &leftv, &lefttopv); | |||
| encode_422_bitstream(s, width-4); | |||
| y++; cy++; | |||
| @@ -1006,16 +980,16 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, | |||
| if(s->bitstream_bpp==12){ | |||
| while(2*cy > y){ | |||
| ydst= s->picture[0] + s->linesize[0]*y; | |||
| ydst= p->data[0] + p->linesize[0]*y; | |||
| sub_median_prediction(s->temp[0], ydst - fake_ystride, ydst, width , &lefty, &lefttopy); | |||
| encode_gray_bitstream(s, width); | |||
| y++; | |||
| } | |||
| if(y>=height) break; | |||
| } | |||
| ydst= s->picture[0] + s->linesize[0]*y; | |||
| udst= s->picture[1] + s->linesize[1]*cy; | |||
| vdst= s->picture[2] + s->linesize[2]*cy; | |||
| ydst= p->data[0] + p->linesize[0]*y; | |||
| udst= p->data[1] + p->linesize[1]*cy; | |||
| vdst= p->data[2] + p->linesize[2]*cy; | |||
| sub_median_prediction(s->temp[0], ydst - fake_ystride, ydst, width , &lefty, &lefttopy); | |||
| sub_median_prediction(s->temp[1], udst - fake_ustride, udst, width2, &leftu, &lefttopu); | |||
| @@ -1029,7 +1003,7 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, | |||
| /* encode a luma only line & y++ */ | |||
| if(s->bitstream_bpp==12){ | |||
| ydst= s->picture[0] + s->linesize[0]*y; | |||
| ydst= p->data[0] + p->linesize[0]*y; | |||
| if(s->predictor == PLANE && s->interlaced < y){ | |||
| s->dsp.diff_bytes(s->temp[1], ydst, ydst - fake_ystride, width); | |||
| @@ -1043,9 +1017,9 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, | |||
| if(y>=height) break; | |||
| } | |||
| ydst= s->picture[0] + s->linesize[0]*y; | |||
| udst= s->picture[1] + s->linesize[1]*cy; | |||
| vdst= s->picture[2] + s->linesize[2]*cy; | |||
| ydst= p->data[0] + p->linesize[0]*y; | |||
| udst= p->data[1] + p->linesize[1]*cy; | |||
| vdst= p->data[2] + p->linesize[2]*cy; | |||
| if(s->predictor == PLANE && s->interlaced < cy){ | |||
| s->dsp.diff_bytes(s->temp[1], ydst, ydst - fake_ystride, width); | |||
| @@ -1088,11 +1062,8 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, | |||
| bswap_buf((uint32_t*)buf, (uint32_t*)buf, size); | |||
| } | |||
| avctx->key_frame= 1; | |||
| avctx->pict_type= I_TYPE; | |||
| s->picture_number++; | |||
| return size*4; | |||
| } | |||
| @@ -1180,9 +1180,11 @@ static int mjpeg_decode_app(MJpegDecodeContext *s) | |||
| get_bits(&s->gb, 8), get_bits(&s->gb, 8)); | |||
| if (get_bits(&s->gb, 8) == 0) | |||
| { | |||
| s->avctx->aspect_ratio_info = FF_ASPECT_EXTENDED; | |||
| s->avctx->aspected_width = get_bits(&s->gb, 16); | |||
| s->avctx->aspected_height = get_bits(&s->gb, 16); | |||
| int x_density = get_bits(&s->gb, 16); | |||
| int y_density = get_bits(&s->gb, 16); | |||
| //MN: needs to be checked | |||
| s->avctx->aspect_ratio= s->width*y_density/((float)s->height*x_density); | |||
| } | |||
| else | |||
| { | |||
| @@ -1468,7 +1470,7 @@ eoi_parser: | |||
| } | |||
| /* dummy quality */ | |||
| /* XXX: infer it with matrix */ | |||
| avctx->quality = 3; | |||
| // avctx->quality = 3; | |||
| goto the_end; | |||
| } | |||
| break; | |||
| @@ -1635,7 +1637,7 @@ read_header: | |||
| } | |||
| /* dummy quality */ | |||
| /* XXX: infer it with matrix */ | |||
| avctx->quality = 3; | |||
| // avctx->quality = 3; | |||
| return buf_ptr - buf; | |||
| } | |||
| @@ -92,7 +92,7 @@ static int full_motion_search(MpegEncContext * s, | |||
| y2 = yy + range - 1; | |||
| if (y2 > ymax) | |||
| y2 = ymax; | |||
| pix = s->new_picture[0] + (yy * s->linesize) + xx; | |||
| pix = s->new_picture.data[0] + (yy * s->linesize) + xx; | |||
| dmin = 0x7fffffff; | |||
| mx = 0; | |||
| my = 0; | |||
| @@ -155,7 +155,7 @@ static int log_motion_search(MpegEncContext * s, | |||
| if (y2 > ymax) | |||
| y2 = ymax; | |||
| pix = s->new_picture[0] + (yy * s->linesize) + xx; | |||
| pix = s->new_picture.data[0] + (yy * s->linesize) + xx; | |||
| dmin = 0x7fffffff; | |||
| mx = 0; | |||
| my = 0; | |||
| @@ -231,7 +231,7 @@ static int phods_motion_search(MpegEncContext * s, | |||
| if (y2 > ymax) | |||
| y2 = ymax; | |||
| pix = s->new_picture[0] + (yy * s->linesize) + xx; | |||
| pix = s->new_picture.data[0] + (yy * s->linesize) + xx; | |||
| mx = 0; | |||
| my = 0; | |||
| @@ -560,7 +560,7 @@ static int epzs_motion_search(MpegEncContext * s, | |||
| uint16_t *score_map= s->me_score_map; | |||
| int map_generation; | |||
| new_pic = s->new_picture[0] + pic_xy; | |||
| new_pic = s->new_picture.data[0] + pic_xy; | |||
| old_pic = ref_picture + pic_xy; | |||
| map_generation= update_map_generation(s); | |||
| @@ -649,7 +649,7 @@ static int epzs_motion_search4(MpegEncContext * s, int block, | |||
| uint16_t *score_map= s->me_score_map; | |||
| int map_generation; | |||
| new_pic = s->new_picture[0] + pic_xy; | |||
| new_pic = s->new_picture.data[0] + pic_xy; | |||
| old_pic = ref_picture + pic_xy; | |||
| map_generation= update_map_generation(s); | |||
| @@ -723,7 +723,7 @@ static inline int halfpel_motion_search(MpegEncContext * s, | |||
| xx = 16 * s->mb_x + 8*(n&1); | |||
| yy = 16 * s->mb_y + 8*(n>>1); | |||
| pix = s->new_picture[0] + (yy * s->linesize) + xx; | |||
| pix = s->new_picture.data[0] + (yy * s->linesize) + xx; | |||
| mx = *mx_ptr; | |||
| my = *my_ptr; | |||
| @@ -789,7 +789,7 @@ static inline int fast_halfpel_motion_search(MpegEncContext * s, | |||
| xx = 16 * s->mb_x + 8*(n&1); | |||
| yy = 16 * s->mb_y + 8*(n>>1); | |||
| pix = s->new_picture[0] + (yy * s->linesize) + xx; | |||
| pix = s->new_picture.data[0] + (yy * s->linesize) + xx; | |||
| mx = *mx_ptr; | |||
| my = *my_ptr; | |||
| @@ -931,7 +931,7 @@ static inline int mv4_search(MpegEncContext *s, int xmin, int ymin, int xmax, in | |||
| { | |||
| int block; | |||
| int P[10][2]; | |||
| uint8_t *ref_picture= s->last_picture[0]; | |||
| uint8_t *ref_picture= s->last_picture.data[0]; | |||
| int dmin_sum=0; | |||
| for(block=0; block<4; block++){ | |||
| @@ -1019,7 +1019,8 @@ void ff_estimate_p_frame_motion(MpegEncContext * s, | |||
| int P[10][2]; | |||
| const int shift= 1+s->quarter_sample; | |||
| int mb_type=0; | |||
| uint8_t *ref_picture= s->last_picture[0]; | |||
| uint8_t *ref_picture= s->last_picture.data[0]; | |||
| Picture * const pic= &s->current_picture; | |||
| get_limits(s, &range, &xmin, &ymin, &xmax, &ymax, s->f_code); | |||
| rel_xmin= xmin - mb_x*16; | |||
| @@ -1104,7 +1105,7 @@ void ff_estimate_p_frame_motion(MpegEncContext * s, | |||
| xx = mb_x * 16; | |||
| yy = mb_y * 16; | |||
| pix = s->new_picture[0] + (yy * s->linesize) + xx; | |||
| pix = s->new_picture.data[0] + (yy * s->linesize) + xx; | |||
| /* At this point (mx,my) are full-pell and the relative displacement */ | |||
| ppix = ref_picture + ((yy+my) * s->linesize) + (xx+mx); | |||
| @@ -1115,11 +1116,11 @@ void ff_estimate_p_frame_motion(MpegEncContext * s, | |||
| vard = (s->dsp.pix_norm(pix, ppix, s->linesize)+128)>>8; | |||
| //printf("%d %d %d %X %X %X\n", s->mb_width, mb_x, mb_y,(int)s, (int)s->mb_var, (int)s->mc_mb_var); fflush(stdout); | |||
| s->mb_var [s->mb_width * mb_y + mb_x] = varc; | |||
| s->mc_mb_var[s->mb_width * mb_y + mb_x] = vard; | |||
| s->mb_mean [s->mb_width * mb_y + mb_x] = (sum+128)>>8; | |||
| s->mb_var_sum += varc; | |||
| s->mc_mb_var_sum += vard; | |||
| pic->mb_var [s->mb_width * mb_y + mb_x] = varc; | |||
| pic->mc_mb_var[s->mb_width * mb_y + mb_x] = vard; | |||
| pic->mb_mean [s->mb_width * mb_y + mb_x] = (sum+128)>>8; | |||
| pic->mb_var_sum += varc; | |||
| pic->mc_mb_var_sum += vard; | |||
| //printf("E%d %d %d %X %X %X\n", s->mb_width, mb_x, mb_y,(int)s, (int)s->mb_var, (int)s->mc_mb_var); fflush(stdout); | |||
| #if 0 | |||
| @@ -1318,7 +1319,7 @@ static inline int check_bidir_mv(MpegEncContext * s, | |||
| if (src_y == s->height) | |||
| dxy&= 1; | |||
| ptr = s->last_picture[0] + (src_y * s->linesize) + src_x; | |||
| ptr = s->last_picture.data[0] + (src_y * s->linesize) + src_x; | |||
| s->dsp.put_pixels_tab[0][dxy](dest_y , ptr , s->linesize, 16); | |||
| fbmin += (mv_penalty[motion_bx-pred_bx] + mv_penalty[motion_by-pred_by])*s->qscale; | |||
| @@ -1333,10 +1334,10 @@ static inline int check_bidir_mv(MpegEncContext * s, | |||
| if (src_y == s->height) | |||
| dxy&= 1; | |||
| ptr = s->next_picture[0] + (src_y * s->linesize) + src_x; | |||
| ptr = s->next_picture.data[0] + (src_y * s->linesize) + src_x; | |||
| s->dsp.avg_pixels_tab[0][dxy](dest_y , ptr , s->linesize, 16); | |||
| fbmin += s->dsp.pix_abs16x16(s->new_picture[0] + mb_x*16 + mb_y*16*s->linesize, dest_y, s->linesize); | |||
| fbmin += s->dsp.pix_abs16x16(s->new_picture.data[0] + mb_x*16 + mb_y*16*s->linesize, dest_y, s->linesize); | |||
| return fbmin; | |||
| } | |||
| @@ -1418,7 +1419,7 @@ static inline int direct_search(MpegEncContext * s, | |||
| src_y = clip(src_y, -16, height); | |||
| if (src_y == height) dxy &= ~2; | |||
| ptr = s->last_picture[0] + (src_y * s->linesize) + src_x; | |||
| ptr = s->last_picture.data[0] + (src_y * s->linesize) + src_x; | |||
| s->dsp.put_pixels_tab[0][dxy](dest_y , ptr , s->linesize, 16); | |||
| dxy = ((motion_by & 1) << 1) | (motion_bx & 1); | |||
| @@ -1511,8 +1512,8 @@ void ff_estimate_b_frame_motion(MpegEncContext * s, | |||
| dmin= direct_search(s, mb_x, mb_y); | |||
| fmin= ff_estimate_motion_b(s, mb_x, mb_y, s->b_forw_mv_table, s->last_picture[0], s->f_code); | |||
| bmin= ff_estimate_motion_b(s, mb_x, mb_y, s->b_back_mv_table, s->next_picture[0], s->b_code) - quant; | |||
| fmin= ff_estimate_motion_b(s, mb_x, mb_y, s->b_forw_mv_table, s->last_picture.data[0], s->f_code); | |||
| bmin= ff_estimate_motion_b(s, mb_x, mb_y, s->b_back_mv_table, s->next_picture.data[0], s->b_code) - quant; | |||
| //printf(" %d %d ", s->b_forw_mv_table[xy][0], s->b_forw_mv_table[xy][1]); | |||
| fbmin= bidir_refine(s, mb_x, mb_y); | |||
| @@ -1534,8 +1535,8 @@ void ff_estimate_b_frame_motion(MpegEncContext * s, | |||
| type= MB_TYPE_BIDIR; | |||
| } | |||
| score= ((unsigned)(score*score + 128*256))>>16; | |||
| s->mc_mb_var_sum += score; | |||
| s->mc_mb_var[mb_y*s->mb_width + mb_x] = score; //FIXME use SSD | |||
| s->current_picture.mc_mb_var_sum += score; | |||
| s->current_picture.mc_mb_var[mb_y*s->mb_width + mb_x] = score; //FIXME use SSD | |||
| } | |||
| if(s->flags&CODEC_FLAG_HQ){ | |||
| @@ -1581,7 +1582,7 @@ int ff_get_best_fcode(MpegEncContext * s, int16_t (*mv_table)[2], int type) | |||
| int j; | |||
| for(j=0; j<fcode && j<8; j++){ | |||
| if(s->pict_type==B_TYPE || s->mc_mb_var[i] < s->mb_var[i]) | |||
| if(s->pict_type==B_TYPE || s->current_picture.mc_mb_var[i] < s->current_picture.mb_var[i]) | |||
| score[j]-= 170; | |||
| } | |||
| } | |||
| @@ -134,7 +134,7 @@ static void mpeg1_encode_sequence_header(MpegEncContext *s) | |||
| int n; | |||
| UINT64 time_code; | |||
| if (s->picture_in_gop_number == 0) { | |||
| if (s->current_picture.key_frame) { | |||
| /* mpeg1 header repeated every gop */ | |||
| put_header(s, SEQ_START_CODE); | |||
| @@ -1359,7 +1359,6 @@ static int mpeg_decode_init(AVCodecContext *avctx) | |||
| s->mpeg_enc_ctx.picture_number = 0; | |||
| s->repeat_field = 0; | |||
| s->mpeg_enc_ctx.codec_id= avctx->codec->id; | |||
| avctx->mbskip_table= s->mpeg_enc_ctx.mbskip_table; | |||
| return 0; | |||
| } | |||
| @@ -1403,9 +1402,6 @@ static int mpeg1_decode_picture(AVCodecContext *avctx, | |||
| s->pict_type = get_bits(&s->gb, 3); | |||
| dprintf("pict_type=%d number=%d\n", s->pict_type, s->picture_number); | |||
| avctx->pict_type= s->pict_type; | |||
| avctx->key_frame= s->pict_type == I_TYPE; | |||
| skip_bits(&s->gb, 16); | |||
| if (s->pict_type == P_TYPE || s->pict_type == B_TYPE) { | |||
| s->full_pel[0] = get_bits1(&s->gb); | |||
| @@ -1423,6 +1419,8 @@ static int mpeg1_decode_picture(AVCodecContext *avctx, | |||
| s->mpeg_f_code[1][0] = f_code; | |||
| s->mpeg_f_code[1][1] = f_code; | |||
| } | |||
| s->current_picture.pict_type= s->pict_type; | |||
| s->current_picture.key_frame= s->pict_type == I_TYPE; | |||
| s->y_dc_scale = 8; | |||
| s->c_dc_scale = 8; | |||
| s->first_slice = 1; | |||
| @@ -1576,7 +1574,7 @@ static void mpeg_decode_extension(AVCodecContext *avctx, | |||
| * DECODE_SLICE_EOP if the end of the picture is reached | |||
| */ | |||
| static int mpeg_decode_slice(AVCodecContext *avctx, | |||
| AVPicture *pict, | |||
| AVVideoFrame *pict, | |||
| int start_code, | |||
| UINT8 *buf, int buf_size) | |||
| { | |||
| @@ -1677,38 +1675,25 @@ eos: //end of slice | |||
| if (/*s->mb_x == 0 &&*/ | |||
| s->mb_y == s->mb_height) { | |||
| /* end of image */ | |||
| UINT8 **picture; | |||
| if(s->mpeg2) | |||
| s->qscale >>=1; | |||
| MPV_frame_end(s); | |||
| if (s->pict_type == B_TYPE) { | |||
| picture = s->current_picture; | |||
| avctx->quality = s->qscale; | |||
| *pict= *(AVVideoFrame*)&s->current_picture; | |||
| } else { | |||
| s->picture_number++; | |||
| /* latency of 1 frame for I and P frames */ | |||
| /* XXX: use another variable than picture_number */ | |||
| if (s->picture_number == 0) { | |||
| picture = NULL; | |||
| if (s->picture_number == 1) { | |||
| return DECODE_SLICE_OK; | |||
| } else { | |||
| picture = s->last_picture; | |||
| avctx->quality = s->last_qscale; | |||
| *pict= *(AVVideoFrame*)&s->last_picture; | |||
| } | |||
| s->last_qscale = s->qscale; | |||
| s->picture_number++; | |||
| } | |||
| if(s->mpeg2) | |||
| avctx->quality>>=1; | |||
| if (picture) { | |||
| pict->data[0] = picture[0]; | |||
| pict->data[1] = picture[1]; | |||
| pict->data[2] = picture[2]; | |||
| pict->linesize[0] = s->linesize; | |||
| pict->linesize[1] = s->uvlinesize; | |||
| pict->linesize[2] = s->uvlinesize; | |||
| return DECODE_SLICE_EOP; | |||
| } else { | |||
| return DECODE_SLICE_OK; | |||
| } | |||
| return DECODE_SLICE_EOP; | |||
| } else { | |||
| return DECODE_SLICE_OK; | |||
| } | |||
| @@ -1827,7 +1812,7 @@ static int mpeg_decode_frame(AVCodecContext *avctx, | |||
| Mpeg1Context *s = avctx->priv_data; | |||
| UINT8 *buf_end, *buf_ptr, *buf_start; | |||
| int len, start_code_found, ret, code, start_code, input_size; | |||
| AVPicture *picture = data; | |||
| AVVideoFrame *picture = data; | |||
| MpegEncContext *s2 = &s->mpeg_enc_ctx; | |||
| dprintf("fill_buffer\n"); | |||
| @@ -1837,13 +1822,9 @@ static int mpeg_decode_frame(AVCodecContext *avctx, | |||
| /* special case for last picture */ | |||
| if (buf_size == 0) { | |||
| if (s2->picture_number > 0) { | |||
| picture->data[0] = s2->next_picture[0]; | |||
| picture->data[1] = s2->next_picture[1]; | |||
| picture->data[2] = s2->next_picture[2]; | |||
| picture->linesize[0] = s2->linesize; | |||
| picture->linesize[1] = s2->uvlinesize; | |||
| picture->linesize[2] = s2->uvlinesize; | |||
| *data_size = sizeof(AVPicture); | |||
| *picture= *(AVVideoFrame*)&s2->next_picture; | |||
| *data_size = sizeof(AVVideoFrame); | |||
| } | |||
| return 0; | |||
| } | |||
| @@ -46,7 +46,6 @@ void (*draw_edges)(UINT8 *buf, int wrap, int width, int height, int w)= draw_edg | |||
| static void emulated_edge_mc(MpegEncContext *s, UINT8 *src, int linesize, int block_w, int block_h, | |||
| int src_x, int src_y, int w, int h); | |||
| #define EDGE_WIDTH 16 | |||
| /* enable all paranoid tests for rounding, overflows, etc... */ | |||
| //#define PARANOID | |||
| @@ -268,10 +267,47 @@ int DCT_common_init(MpegEncContext *s) | |||
| return 0; | |||
| } | |||
| /** | |||
| * allocates various arrays for a Picture structure, except the pixels themself. | |||
| * The pixels are allocated/set in te get_buffer() | |||
| */ | |||
| static int alloc_picture(MpegEncContext *s, Picture *pic){ | |||
| if (s->encoding) { | |||
| CHECKED_ALLOCZ(pic->mb_var , s->mb_num * sizeof(INT16)) | |||
| CHECKED_ALLOCZ(pic->mc_mb_var, s->mb_num * sizeof(INT16)) | |||
| CHECKED_ALLOCZ(pic->mb_mean , s->mb_num * sizeof(INT8)) | |||
| } | |||
| CHECKED_ALLOCZ(pic->mbskip_table , s->mb_num * sizeof(UINT8)+1) //the +1 is for the slice end check | |||
| CHECKED_ALLOCZ(pic->qscale_table , s->mb_num * sizeof(UINT8)) | |||
| pic->qstride= s->mb_width; | |||
| return 0; | |||
| fail: //for the CHECKED_ALLOCZ macro | |||
| return -1; | |||
| } | |||
| static void free_picture(MpegEncContext *s, Picture *pic){ | |||
| int i; | |||
| av_freep(&pic->mb_var); | |||
| av_freep(&pic->mc_mb_var); | |||
| av_freep(&pic->mb_mean); | |||
| av_freep(&pic->mbskip_table); | |||
| av_freep(&pic->qscale_table); | |||
| if(s->avctx->get_buffer == avcodec_default_get_buffer){ | |||
| for(i=0; i<4; i++){ | |||
| av_freep(&pic->base[i]); | |||
| pic->data[i]= NULL; | |||
| } | |||
| av_freep(&pic->opaque); | |||
| } | |||
| } | |||
| /* init common structure for both encoder and decoder */ | |||
| int MPV_common_init(MpegEncContext *s) | |||
| { | |||
| UINT8 *pict; | |||
| int y_size, c_size, yc_size, i; | |||
| dsputil_init(&s->dsp, s->avctx->dsp_mask); | |||
| @@ -279,7 +315,7 @@ int MPV_common_init(MpegEncContext *s) | |||
| s->flags= s->avctx->flags; | |||
| s->mb_width = (s->width + 15) / 16; | |||
| s->mb_width = (s->width + 15) / 16; | |||
| s->mb_height = (s->height + 15) / 16; | |||
| /* set default edge pos, will be overriden in decode_header if needed */ | |||
| @@ -298,51 +334,12 @@ int MPV_common_init(MpegEncContext *s) | |||
| + (toupper((s->avctx->fourcc>>16)&0xFF)<<16) | |||
| + (toupper((s->avctx->fourcc>>24)&0xFF)<<24); | |||
| if(!(s->flags&CODEC_FLAG_DR1)){ | |||
| s->linesize = s->mb_width * 16 + 2 * EDGE_WIDTH; | |||
| s->uvlinesize = s->mb_width * 8 + EDGE_WIDTH; | |||
| for(i=0;i<3;i++) { | |||
| int w, h, shift, pict_start; | |||
| unsigned size; | |||
| w = s->linesize; | |||
| h = s->mb_height * 16 + 2 * EDGE_WIDTH; | |||
| shift = (i == 0) ? 0 : 1; | |||
| size = (s->linesize>>shift) * (h >> shift); | |||
| pict_start = (s->linesize>>shift) * (EDGE_WIDTH >> shift) + (EDGE_WIDTH >> shift); | |||
| CHECKED_ALLOCZ(pict, size) | |||
| s->last_picture_base[i] = pict; | |||
| s->last_picture[i] = pict + pict_start; | |||
| if(i>0) memset(s->last_picture_base[i], 128, size); | |||
| CHECKED_ALLOCZ(pict, size) | |||
| s->next_picture_base[i] = pict; | |||
| s->next_picture[i] = pict + pict_start; | |||
| if(i>0) memset(s->next_picture_base[i], 128, size); | |||
| if (s->has_b_frames || s->codec_id==CODEC_ID_MPEG4) { | |||
| /* Note the MPEG4 stuff is here cuz of buggy encoders which dont set the low_delay flag but | |||
| do low-delay encoding, so we cant allways distinguish b-frame containing streams from low_delay streams */ | |||
| CHECKED_ALLOCZ(pict, size) | |||
| s->aux_picture_base[i] = pict; | |||
| s->aux_picture[i] = pict + pict_start; | |||
| if(i>0) memset(s->aux_picture_base[i], 128, size); | |||
| } | |||
| } | |||
| s->ip_buffer_count= 2; | |||
| } | |||
| CHECKED_ALLOCZ(s->edge_emu_buffer, (s->width+64)*2*17*2); //(width + edge + align)*interlaced*MBsize*tolerance | |||
| s->avctx->coded_picture= (AVVideoFrame*)&s->current_picture; | |||
| if (s->encoding) { | |||
| int j; | |||
| int mv_table_size= (s->mb_width+2)*(s->mb_height+2); | |||
| CHECKED_ALLOCZ(s->mb_var , s->mb_num * sizeof(INT16)) | |||
| CHECKED_ALLOCZ(s->mc_mb_var, s->mb_num * sizeof(INT16)) | |||
| CHECKED_ALLOCZ(s->mb_mean , s->mb_num * sizeof(INT8)) | |||
| /* Allocate MV tables */ | |||
| CHECKED_ALLOCZ(s->p_mv_table , mv_table_size * 2 * sizeof(INT16)) | |||
| @@ -354,28 +351,12 @@ int MPV_common_init(MpegEncContext *s) | |||
| CHECKED_ALLOCZ(s->b_direct_back_mv_table, mv_table_size * 2 * sizeof(INT16)) | |||
| CHECKED_ALLOCZ(s->b_direct_mv_table , mv_table_size * 2 * sizeof(INT16)) | |||
| CHECKED_ALLOCZ(s->me_scratchpad, s->linesize*16*3*sizeof(uint8_t)) | |||
| //FIXME should be linesize instead of s->width*2 but that isnt known before get_buffer() | |||
| CHECKED_ALLOCZ(s->me_scratchpad, s->width*2*16*3*sizeof(uint8_t)) | |||
| CHECKED_ALLOCZ(s->me_map , ME_MAP_SIZE*sizeof(uint32_t)) | |||
| CHECKED_ALLOCZ(s->me_score_map, ME_MAP_SIZE*sizeof(uint16_t)) | |||
| if(s->max_b_frames){ | |||
| for(j=0; j<REORDER_BUFFER_SIZE; j++){ | |||
| int i; | |||
| for(i=0;i<3;i++) { | |||
| int w, h, shift, size; | |||
| w = s->linesize; | |||
| h = s->mb_height * 16; | |||
| shift = (i == 0) ? 0 : 1; | |||
| size = (w >> shift) * (h >> shift); | |||
| CHECKED_ALLOCZ(pict, size); | |||
| s->picture_buffer[j][i] = pict; | |||
| } | |||
| } | |||
| } | |||
| if(s->codec_id==CODEC_ID_MPEG4){ | |||
| CHECKED_ALLOCZ(s->tex_pb_buffer, PB_BUFFER_SIZE); | |||
| CHECKED_ALLOCZ( s->pb2_buffer, PB_BUFFER_SIZE); | |||
| @@ -434,12 +415,6 @@ int MPV_common_init(MpegEncContext *s) | |||
| s->dc_val[0][i] = 1024; | |||
| } | |||
| CHECKED_ALLOCZ(s->next_qscale_table , s->mb_num * sizeof(UINT8)) | |||
| CHECKED_ALLOCZ(s->last_qscale_table , s->mb_num * sizeof(UINT8)) | |||
| CHECKED_ALLOCZ(s->aux_qscale_table , s->mb_num * sizeof(UINT8)) | |||
| s->qscale_table= s->next_qscale_table; | |||
| s->avctx->qstride= s->mb_width; | |||
| /* which mb is a intra block */ | |||
| CHECKED_ALLOCZ(s->mbintra_table, s->mb_num); | |||
| memset(s->mbintra_table, 1, s->mb_num); | |||
| @@ -470,10 +445,13 @@ void MPV_common_end(MpegEncContext *s) | |||
| { | |||
| int i; | |||
| for(i=0; i<MAX_PICTURE_COUNT; i++){ | |||
| if(s->picture[i].data[0]){ | |||
| s->avctx->release_buffer(s->avctx, (AVVideoFrame*)&s->picture[i]); | |||
| } | |||
| } | |||
| av_freep(&s->mb_type); | |||
| av_freep(&s->mb_var); | |||
| av_freep(&s->mc_mb_var); | |||
| av_freep(&s->mb_mean); | |||
| av_freep(&s->p_mv_table); | |||
| av_freep(&s->b_forw_mv_table); | |||
| av_freep(&s->b_back_mv_table); | |||
| @@ -489,9 +467,6 @@ void MPV_common_end(MpegEncContext *s) | |||
| av_freep(&s->mbintra_table); | |||
| av_freep(&s->cbp_table); | |||
| av_freep(&s->pred_dir_table); | |||
| av_freep(&s->next_qscale_table); | |||
| av_freep(&s->last_qscale_table); | |||
| av_freep(&s->aux_qscale_table); | |||
| av_freep(&s->me_scratchpad); | |||
| av_freep(&s->me_map); | |||
| av_freep(&s->me_score_map); | |||
| @@ -507,24 +482,9 @@ void MPV_common_end(MpegEncContext *s) | |||
| av_freep(&s->avctx->stats_out); | |||
| av_freep(&s->ac_stats); | |||
| av_freep(&s->error_status_table); | |||
| for(i=0;i<3;i++) { | |||
| int j; | |||
| if(!(s->flags&CODEC_FLAG_DR1)){ | |||
| av_freep(&s->last_picture_base[i]); | |||
| av_freep(&s->next_picture_base[i]); | |||
| av_freep(&s->aux_picture_base[i]); | |||
| } | |||
| s->last_picture_base[i]= | |||
| s->next_picture_base[i]= | |||
| s->aux_picture_base [i] = NULL; | |||
| s->last_picture[i]= | |||
| s->next_picture[i]= | |||
| s->aux_picture [i] = NULL; | |||
| for(j=0; j<REORDER_BUFFER_SIZE; j++){ | |||
| av_freep(&s->picture_buffer[j][i]); | |||
| } | |||
| for(i=0; i<MAX_PICTURE_COUNT; i++){ | |||
| free_picture(s, &s->picture[i]); | |||
| } | |||
| s->context_initialized = 0; | |||
| } | |||
| @@ -813,70 +773,70 @@ static void draw_edges_c(UINT8 *buf, int wrap, int width, int height, int w) | |||
| /* generic function for encode/decode called before a frame is coded/decoded */ | |||
| int MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx) | |||
| { | |||
| int i; | |||
| UINT8 *tmp; | |||
| int i, r; | |||
| AVVideoFrame *pic; | |||
| s->mb_skiped = 0; | |||
| avctx->mbskip_table= s->mbskip_table; | |||
| s->hurry_up= s->avctx->hurry_up; | |||
| s->error_resilience= avctx->error_resilience; | |||
| if(avctx->flags&CODEC_FLAG_DR1){ | |||
| if(avctx->get_buffer_callback(avctx, s->width, s->height, s->pict_type) < 0){ | |||
| fprintf(stderr, "get_buffer() failed\n"); | |||
| return -1; | |||
| /* mark&release old frames */ | |||
| if (s->pict_type != B_TYPE && s->last_picture.data[0]) { | |||
| Picture *pic= NULL; | |||
| for(i=0; i<MAX_PICTURE_COUNT; i++){ | |||
| if(s->picture[i].data[0] == s->last_picture.data[0]){ | |||
| // s->picture[i].reference=0; | |||
| avctx->release_buffer(avctx, (AVVideoFrame*)&s->picture[i]); | |||
| break; | |||
| } | |||
| } | |||
| assert(i<MAX_PICTURE_COUNT); | |||
| /* release forgotten pictures */ | |||
| /* if(mpeg124/h263) */ | |||
| if(!s->encoding){ | |||
| for(i=0; i<MAX_PICTURE_COUNT; i++){ | |||
| if(s->picture[i].data[0] && s->picture[i].data[0] != s->next_picture.data[0] && s->picture[i].reference){ | |||
| fprintf(stderr, "releasing zombie picture\n"); | |||
| avctx->release_buffer(avctx, (AVVideoFrame*)&s->picture[i]); | |||
| } | |||
| } | |||
| } | |||
| s->linesize = avctx->dr_stride; | |||
| s->uvlinesize= avctx->dr_uvstride; | |||
| s->ip_buffer_count= avctx->dr_ip_buffer_count; | |||
| } | |||
| avctx->dr_ip_buffer_count= s->ip_buffer_count; | |||
| if (s->pict_type == B_TYPE) { | |||
| for(i=0;i<3;i++) { | |||
| if(avctx->flags&CODEC_FLAG_DR1) | |||
| s->aux_picture[i]= avctx->dr_buffer[i]; | |||
| //FIXME the following should never be needed, the decoder should drop b frames if no reference is available | |||
| if(s->next_picture[i]==NULL) | |||
| s->next_picture[i]= s->aux_picture[i]; | |||
| if(s->last_picture[i]==NULL) | |||
| s->last_picture[i]= s->next_picture[i]; | |||
| s->current_picture[i] = s->aux_picture[i]; | |||
| if(!s->encoding){ | |||
| /* find unused Picture */ | |||
| for(i=0; i<MAX_PICTURE_COUNT; i++){ | |||
| if(s->picture[i].data[0]==NULL) break; | |||
| } | |||
| assert(i<MAX_PICTURE_COUNT); | |||
| pic= (AVVideoFrame*)&s->picture[i]; | |||
| pic->reference= s->pict_type != B_TYPE; | |||
| pic->coded_picture_number= s->current_picture.coded_picture_number+1; | |||
| r= avctx->get_buffer(avctx, pic); | |||
| if(r<0 || (s->linesize && (s->linesize != pic->linesize[0] || s->uvlinesize != pic->linesize[1]))){ | |||
| fprintf(stderr, "get_buffer() failed (stride changed), bye bye\n"); | |||
| return -1; | |||
| } | |||
| s->avctx->display_qscale_table= | |||
| s->avctx->current_qscale_table= | |||
| s->qscale_table= s->aux_qscale_table; | |||
| } else { | |||
| for(i=0;i<3;i++) { | |||
| /* swap next and last */ | |||
| if(avctx->flags&CODEC_FLAG_DR1) | |||
| tmp= avctx->dr_buffer[i]; | |||
| else | |||
| tmp = s->last_picture[i]; | |||
| s->last_picture[i] = s->next_picture[i]; | |||
| s->next_picture[i] = tmp; | |||
| s->current_picture[i] = tmp; | |||
| s->linesize = pic->linesize[0]; | |||
| s->uvlinesize= pic->linesize[1]; | |||
| if(pic->qscale_table==NULL) | |||
| alloc_picture(s, (Picture*)pic); | |||
| if(s->last_picture[i]==NULL) | |||
| s->last_picture[i]= s->next_picture[i]; | |||
| s->current_picture= s->picture[i]; | |||
| } | |||
| s->last_dr_opaque= s->next_dr_opaque; | |||
| s->next_dr_opaque= avctx->dr_opaque_frame; | |||
| s->hurry_up= s->avctx->hurry_up; | |||
| s->error_resilience= avctx->error_resilience; | |||
| if(s->has_b_frames && s->last_dr_opaque && s->codec_id!=CODEC_ID_SVQ1) | |||
| avctx->dr_opaque_frame= s->last_dr_opaque; | |||
| else | |||
| avctx->dr_opaque_frame= s->next_dr_opaque; | |||
| } | |||
| s->avctx->current_qscale_table= s->qscale_table = s->last_qscale_table; | |||
| s->avctx->display_qscale_table= s->last_qscale_table = s->next_qscale_table; | |||
| s->next_qscale_table= s->qscale_table; | |||
| if (s->pict_type != B_TYPE) { | |||
| s->last_picture= s->next_picture; | |||
| s->next_picture= s->current_picture; | |||
| } | |||
| /* set dequantizer, we cant do it during init as it might change for mpeg4 | |||
| and we cant do it in the header decode as init isnt called for mpeg4 there yet */ | |||
| if(s->out_format == FMT_H263){ | |||
| @@ -893,14 +853,15 @@ int MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx) | |||
| /* generic function for encode/decode called after a frame has been coded/decoded */ | |||
| void MPV_frame_end(MpegEncContext *s) | |||
| { | |||
| s->avctx->key_frame = (s->pict_type == I_TYPE); | |||
| s->avctx->pict_type = s->pict_type; | |||
| int i; | |||
| /* draw edge for correct motion prediction if outside */ | |||
| if (s->pict_type != B_TYPE && !s->intra_only && !(s->flags&CODEC_FLAG_EMU_EDGE)) { | |||
| draw_edges(s->current_picture[0], s->linesize , s->h_edge_pos , s->v_edge_pos , EDGE_WIDTH ); | |||
| draw_edges(s->current_picture[1], s->uvlinesize, s->h_edge_pos>>1, s->v_edge_pos>>1, EDGE_WIDTH/2); | |||
| draw_edges(s->current_picture[2], s->uvlinesize, s->h_edge_pos>>1, s->v_edge_pos>>1, EDGE_WIDTH/2); | |||
| if(s->codec_id!=CODEC_ID_SVQ1){ | |||
| if (s->pict_type != B_TYPE && !s->intra_only && !(s->flags&CODEC_FLAG_EMU_EDGE)) { | |||
| draw_edges(s->current_picture.data[0], s->linesize , s->h_edge_pos , s->v_edge_pos , EDGE_WIDTH ); | |||
| draw_edges(s->current_picture.data[1], s->uvlinesize, s->h_edge_pos>>1, s->v_edge_pos>>1, EDGE_WIDTH/2); | |||
| draw_edges(s->current_picture.data[2], s->uvlinesize, s->h_edge_pos>>1, s->v_edge_pos>>1, EDGE_WIDTH/2); | |||
| } | |||
| } | |||
| emms_c(); | |||
| @@ -910,84 +871,154 @@ void MPV_frame_end(MpegEncContext *s) | |||
| s->num_available_buffers++; | |||
| if(s->num_available_buffers>2) s->num_available_buffers= 2; | |||
| } | |||
| s->current_picture.quality= s->qscale; //FIXME get average of qscale_table | |||
| s->current_picture.pict_type= s->pict_type; | |||
| s->current_picture.key_frame= s->pict_type == I_TYPE; | |||
| /* copy back current_picture variables */ | |||
| for(i=0; i<MAX_PICTURE_COUNT; i++){ | |||
| if(s->picture[i].data[0] == s->current_picture.data[0]){ | |||
| s->picture[i]= s->current_picture; | |||
| break; | |||
| } | |||
| } | |||
| assert(i<MAX_PICTURE_COUNT); | |||
| /* release non refernce frames */ | |||
| for(i=0; i<MAX_PICTURE_COUNT; i++){ | |||
| if(s->picture[i].data[0] && !s->picture[i].reference) | |||
| s->avctx->release_buffer(s->avctx, (AVVideoFrame*)&s->picture[i]); | |||
| } | |||
| } | |||
| /* reorder input for encoding */ | |||
| void reorder_input(MpegEncContext *s, AVPicture *pict) | |||
| { | |||
| int i, j, index; | |||
| if(s->max_b_frames > FF_MAX_B_FRAMES) s->max_b_frames= FF_MAX_B_FRAMES; | |||
| // delay= s->max_b_frames+1; (or 0 if no b frames cuz decoder diff) | |||
| for(j=0; j<REORDER_BUFFER_SIZE-1; j++){ | |||
| s->coded_order[j]= s->coded_order[j+1]; | |||
| } | |||
| s->coded_order[j].picture[0]= s->coded_order[j].picture[1]= s->coded_order[j].picture[2]= NULL; //catch uninitalized buffers | |||
| s->coded_order[j].pict_type=0; | |||
| switch(s->input_pict_type){ | |||
| default: | |||
| case I_TYPE: | |||
| case S_TYPE: | |||
| case P_TYPE: | |||
| index= s->max_b_frames - s->b_frames_since_non_b; | |||
| s->b_frames_since_non_b=0; | |||
| break; | |||
| case B_TYPE: | |||
| index= s->max_b_frames + 1; | |||
| s->b_frames_since_non_b++; | |||
| break; | |||
| } | |||
| //printf("index:%d type:%d strides: %d %d\n", index, s->input_pict_type, pict->linesize[0], s->linesize); | |||
| if( (index==0 || (s->flags&CODEC_FLAG_INPUT_PRESERVED)) | |||
| && pict->linesize[0] == s->linesize | |||
| && pict->linesize[1] == s->uvlinesize | |||
| && pict->linesize[2] == s->uvlinesize){ | |||
| //printf("ptr\n"); | |||
| for(i=0; i<3; i++){ | |||
| s->coded_order[index].picture[i]= pict->data[i]; | |||
| } | |||
| static int load_input_picture(MpegEncContext *s, AVVideoFrame *pic_arg){ | |||
| AVVideoFrame *pic; | |||
| int i,r; | |||
| const int encoding_delay= s->max_b_frames; | |||
| /* find unused Picture */ | |||
| for(i=0; i<MAX_PICTURE_COUNT; i++){ | |||
| if(s->picture[i].data[0]==NULL) break; | |||
| } | |||
| assert(i<MAX_PICTURE_COUNT); | |||
| pic= (AVVideoFrame*)&s->picture[i]; | |||
| pic->reference= 1; | |||
| // assert(avctx->get_buffer == default_get_buffer || avctx->get_buffer==NULL); | |||
| r= s->avctx->get_buffer(s->avctx, pic); | |||
| if(r<0 || (s->linesize && (s->linesize != pic->linesize[0] || s->uvlinesize != pic->linesize[1]))){ | |||
| fprintf(stderr, "get_buffer() failed (stride changed), bye bye\n"); | |||
| return -1; | |||
| } | |||
| assert(s->linesize==0 || s->linesize ==pic->linesize[0]); | |||
| assert(s->uvlinesize==0 || s->uvlinesize==pic->linesize[1]); | |||
| assert(pic->linesize[1] == pic->linesize[2]); | |||
| s->linesize = pic->linesize[0]; | |||
| s->uvlinesize= pic->linesize[1]; | |||
| if(pic->qscale_table==NULL) | |||
| alloc_picture(s, (Picture*)pic); | |||
| // assert(s->input_picture[0]==NULL || s->input_picture[0]->data[0]==NULL); | |||
| if(s->input_picture[encoding_delay]) | |||
| pic->display_picture_number= s->input_picture[encoding_delay]->display_picture_number + 1; | |||
| //printf("dpn2:%d\n", pic->display_picture_number); | |||
| /* shift buffer entries */ | |||
| for(i=1; i<MAX_PICTURE_COUNT /*s->encoding_delay+1*/; i++) | |||
| s->input_picture[i-1]= s->input_picture[i]; | |||
| s->input_picture[encoding_delay]= (Picture*)pic; | |||
| pic->pict_type= pic_arg->pict_type; | |||
| pic->quality= pic_arg->quality; | |||
| if( pic->data[0] == pic_arg->data[0] | |||
| && pic->data[1] == pic_arg->data[1] | |||
| && pic->data[2] == pic_arg->data[2]){ | |||
| // empty | |||
| }else{ | |||
| //printf("copy\n"); | |||
| int h_chroma_shift, v_chroma_shift; | |||
| avcodec_get_chroma_sub_sample(s->avctx->pix_fmt, &h_chroma_shift, &v_chroma_shift); | |||
| for(i=0; i<3; i++){ | |||
| uint8_t *src = pict->data[i]; | |||
| uint8_t *dest; | |||
| int src_wrap = pict->linesize[i]; | |||
| int dest_wrap = s->linesize; | |||
| int w = s->width; | |||
| int h = s->height; | |||
| if(index==0) dest= s->last_picture[i]+16; //is current_picture indeed but the switch hapens after reordering | |||
| else dest= s->picture_buffer[s->picture_buffer_index][i]; | |||
| if (i >= 1) { | |||
| dest_wrap >>= 1; | |||
| w >>= 1; | |||
| h >>= 1; | |||
| int src_stride= pic_arg->linesize[i]; | |||
| int dst_stride= i ? s->uvlinesize : s->linesize; | |||
| int h_shift= i ? h_chroma_shift : 0; | |||
| int v_shift= i ? v_chroma_shift : 0; | |||
| int w= s->width >>h_shift; | |||
| int h= s->height>>v_shift; | |||
| uint8_t *src= pic_arg->data[i]; | |||
| uint8_t *dst= pic->data[i] + 16; | |||
| if(src_stride==dst_stride) | |||
| memcpy(dst, src, src_stride*h); | |||
| else{ | |||
| while(h--){ | |||
| memcpy(dst, src, w); | |||
| dst += dst_stride; | |||
| src += src_stride; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| s->coded_order[index].picture[i]= dest; | |||
| for(j=0;j<h;j++) { | |||
| memcpy(dest, src, w); | |||
| dest += dest_wrap; | |||
| src += src_wrap; | |||
| return 0; | |||
| } | |||
| static void select_input_picture(MpegEncContext *s){ | |||
| int i; | |||
| const int encoding_delay= s->max_b_frames; | |||
| int coded_pic_num=0; | |||
| if(s->reordered_input_picture[0]) | |||
| coded_pic_num= s->reordered_input_picture[0]->coded_picture_number + 1; | |||
| //printf("cpn:%d\n", coded_pic_num); | |||
| for(i=1; i<MAX_PICTURE_COUNT; i++) | |||
| s->reordered_input_picture[i-1]= s->reordered_input_picture[i]; | |||
| s->reordered_input_picture[MAX_PICTURE_COUNT-1]= NULL; | |||
| /* set next picture types & ordering */ | |||
| if(s->reordered_input_picture[0]==NULL && s->input_picture[0]){ | |||
| if(/*s->picture_in_gop_number >= s->gop_size ||*/ s->next_picture.data[0]==NULL || s->intra_only){ | |||
| s->reordered_input_picture[0]= s->input_picture[0]; | |||
| s->reordered_input_picture[0]->pict_type= I_TYPE; | |||
| s->reordered_input_picture[0]->coded_picture_number= coded_pic_num; | |||
| }else{ | |||
| s->reordered_input_picture[0]= s->input_picture[s->max_b_frames]; | |||
| if(s->picture_in_gop_number + s->max_b_frames >= s->gop_size) | |||
| s->reordered_input_picture[0]->pict_type= I_TYPE; | |||
| else | |||
| s->reordered_input_picture[0]->pict_type= P_TYPE; | |||
| s->reordered_input_picture[0]->coded_picture_number= coded_pic_num; | |||
| for(i=0; i<s->max_b_frames; i++){ | |||
| coded_pic_num++; | |||
| s->reordered_input_picture[i+1]= s->input_picture[i]; | |||
| s->reordered_input_picture[i+1]->pict_type= B_TYPE; | |||
| s->reordered_input_picture[i+1]->coded_picture_number= coded_pic_num; | |||
| } | |||
| } | |||
| if(index!=0){ | |||
| s->picture_buffer_index++; | |||
| if(s->picture_buffer_index >= REORDER_BUFFER_SIZE) s->picture_buffer_index=0; | |||
| } | |||
| } | |||
| s->coded_order[index].pict_type = s->input_pict_type; | |||
| s->coded_order[index].qscale = s->input_qscale; | |||
| s->coded_order[index].force_type= s->force_input_type; | |||
| s->coded_order[index].picture_in_gop_number= s->input_picture_in_gop_number; | |||
| s->coded_order[index].picture_number= s->input_picture_number; | |||
| for(i=0; i<3; i++){ | |||
| s->new_picture[i]= s->coded_order[0].picture[i]; | |||
| if(s->reordered_input_picture[0]){ | |||
| if(s->reordered_input_picture[0]->pict_type==B_TYPE){ | |||
| s->reordered_input_picture[0]->reference=0; | |||
| } | |||
| s->current_picture= *s->reordered_input_picture[0]; | |||
| s->new_picture= s->current_picture; | |||
| s->new_picture.data[0]+=16; | |||
| s->new_picture.data[1]+=16; | |||
| s->new_picture.data[2]+=16; | |||
| s->picture_number= s->new_picture.display_picture_number; | |||
| //printf("dpn:%d\n", s->picture_number); | |||
| }else{ | |||
| memset(&s->new_picture, 0, sizeof(Picture)); | |||
| } | |||
| } | |||
| @@ -995,52 +1026,26 @@ int MPV_encode_picture(AVCodecContext *avctx, | |||
| unsigned char *buf, int buf_size, void *data) | |||
| { | |||
| MpegEncContext *s = avctx->priv_data; | |||
| AVPicture *pict = data; | |||
| s->input_qscale = avctx->quality; | |||
| AVVideoFrame *pic_arg = data; | |||
| init_put_bits(&s->pb, buf, buf_size, NULL, NULL); | |||
| if(avctx->force_type){ | |||
| s->input_pict_type= | |||
| s->force_input_type= avctx->force_type; | |||
| }else if(s->flags&CODEC_FLAG_PASS2){ | |||
| s->input_pict_type= | |||
| s->force_input_type= s->rc_context.entry[s->input_picture_number].new_pict_type; | |||
| }else{ | |||
| s->force_input_type=0; | |||
| if (!s->intra_only) { | |||
| /* first picture of GOP is intra */ | |||
| if (s->input_picture_in_gop_number % s->gop_size==0){ | |||
| s->input_pict_type = I_TYPE; | |||
| }else if(s->max_b_frames==0){ | |||
| s->input_pict_type = P_TYPE; | |||
| }else{ | |||
| if(s->b_frames_since_non_b < s->max_b_frames) //FIXME more IQ | |||
| s->input_pict_type = B_TYPE; | |||
| else | |||
| s->input_pict_type = P_TYPE; | |||
| } | |||
| } else { | |||
| s->input_pict_type = I_TYPE; | |||
| } | |||
| } | |||
| s->picture_in_gop_number++; | |||
| if(s->input_pict_type==I_TYPE) | |||
| s->input_picture_in_gop_number=0; | |||
| load_input_picture(s, pic_arg); | |||
| reorder_input(s, pict); | |||
| select_input_picture(s); | |||
| /* output? */ | |||
| if(s->coded_order[0].picture[0]){ | |||
| s->pict_type= s->coded_order[0].pict_type; | |||
| if (s->fixed_qscale) /* the ratecontrol needs the last qscale so we dont touch it for CBR */ | |||
| s->qscale= s->coded_order[0].qscale; | |||
| s->force_type= s->coded_order[0].force_type; | |||
| s->picture_in_gop_number= s->coded_order[0].picture_in_gop_number; | |||
| s->picture_number= s->coded_order[0].picture_number; | |||
| if(s->new_picture.data[0]){ | |||
| s->pict_type= s->new_picture.pict_type; | |||
| if (s->fixed_qscale){ /* the ratecontrol needs the last qscale so we dont touch it for CBR */ | |||
| s->qscale= (int)(s->new_picture.quality+0.5); | |||
| assert(s->qscale); | |||
| } | |||
| //emms_c(); | |||
| //printf("qs:%f %f %d\n", s->new_picture.quality, s->current_picture.quality, s->qscale); | |||
| MPV_frame_start(s, avctx); | |||
| encode_picture(s, s->picture_number); | |||
| @@ -1059,17 +1064,12 @@ int MPV_encode_picture(AVCodecContext *avctx, | |||
| if (s->out_format == FMT_MJPEG) | |||
| mjpeg_picture_trailer(s); | |||
| if(!s->fixed_qscale) | |||
| avctx->quality = s->qscale; | |||
| if(s->flags&CODEC_FLAG_PASS1) | |||
| ff_write_pass1_stats(s); | |||
| } | |||
| s->input_picture_number++; | |||
| s->input_picture_in_gop_number++; | |||
| flush_put_bits(&s->pb); | |||
| s->frame_bits = (pbBufPtr(&s->pb) - s->pb.buf) * 8; | |||
| @@ -1088,14 +1088,16 @@ if(s->max_b_frames==0) | |||
| fprintf(f, "%7d, %7d, %2.4f\n", pbBufPtr(&s->pb) - s->pb.buf, s->qscale, avctx->psnr_y); | |||
| } | |||
| #endif | |||
| #if 0 | |||
| if (avctx->get_psnr) { | |||
| /* At this point pict->data should have the original frame */ | |||
| /* an s->current_picture should have the coded/decoded frame */ | |||
| get_psnr(pict->data, s->current_picture, | |||
| get_psnr(pict->data, s->current_picture.data, | |||
| pict->linesize, s->linesize, avctx); | |||
| // printf("%f\n", avctx->psnr_y); | |||
| } | |||
| #endif | |||
| return pbBufPtr(&s->pb) - s->pb.buf; | |||
| } | |||
| @@ -1757,7 +1759,7 @@ void MPV_decode_mb(MpegEncContext *s, DCTELEM block[6][64]) | |||
| mb_x = s->mb_x; | |||
| mb_y = s->mb_y; | |||
| s->qscale_table[mb_xy]= s->qscale; | |||
| s->current_picture.qscale_table[mb_xy]= s->qscale; | |||
| /* update DC predictors for P macroblocks */ | |||
| if (!s->mb_intra) { | |||
| @@ -1823,33 +1825,47 @@ void MPV_decode_mb(MpegEncContext *s, DCTELEM block[6][64]) | |||
| op_pixels_func (*op_pix)[4]; | |||
| qpel_mc_func (*op_qpix)[16]; | |||
| /* avoid copy if macroblock skipped in last frame too | |||
| dont touch it for B-frames as they need the skip info from the next p-frame */ | |||
| /* avoid copy if macroblock skipped in last frame too */ | |||
| if (s->pict_type != B_TYPE) { | |||
| s->current_picture.mbskip_table[mb_xy]= s->mb_skiped; | |||
| } | |||
| /* skip only during decoding as we might trash the buffers during encoding a bit */ | |||
| if(!s->encoding){ | |||
| UINT8 *mbskip_ptr = &s->mbskip_table[mb_xy]; | |||
| if (s->mb_skiped) { | |||
| s->mb_skiped = 0; | |||
| const int age= s->current_picture.age; | |||
| assert(age); | |||
| if (s->mb_skiped) { | |||
| s->mb_skiped= 0; | |||
| assert(s->pict_type!=I_TYPE); | |||
| (*mbskip_ptr) ++; /* indicate that this time we skiped it */ | |||
| if(*mbskip_ptr >99) *mbskip_ptr= 99; | |||
| /* if previous was skipped too, then nothing to do ! | |||
| skip only during decoding as we might trash the buffers during encoding a bit */ | |||
| if (*mbskip_ptr >= s->ip_buffer_count && !s->encoding) | |||
| return; | |||
| /* if previous was skipped too, then nothing to do ! */ | |||
| if (*mbskip_ptr >= age){ | |||
| //if(s->pict_type!=B_TYPE && s->mb_x==0) printf("\n"); | |||
| //if(s->pict_type!=B_TYPE) printf("%d%d ", *mbskip_ptr, age); | |||
| if(s->pict_type!=B_TYPE) return; | |||
| if(s->avctx->draw_horiz_band==NULL && *mbskip_ptr > age) return; | |||
| /* we dont draw complete frames here so we cant skip */ | |||
| } | |||
| } else { | |||
| *mbskip_ptr = 0; /* not skipped */ | |||
| } | |||
| } | |||
| }else | |||
| s->mb_skiped= 0; | |||
| if(s->pict_type==B_TYPE && s->avctx->draw_horiz_band){ | |||
| dest_y = s->current_picture [0] + mb_x * 16; | |||
| dest_cb = s->current_picture[1] + mb_x * 8; | |||
| dest_cr = s->current_picture[2] + mb_x * 8; | |||
| dest_y = s->current_picture.data[0] + mb_x * 16; | |||
| dest_cb = s->current_picture.data[1] + mb_x * 8; | |||
| dest_cr = s->current_picture.data[2] + mb_x * 8; | |||
| }else{ | |||
| dest_y = s->current_picture [0] + (mb_y * 16* s->linesize ) + mb_x * 16; | |||
| dest_cb = s->current_picture[1] + (mb_y * 8 * s->uvlinesize) + mb_x * 8; | |||
| dest_cr = s->current_picture[2] + (mb_y * 8 * s->uvlinesize) + mb_x * 8; | |||
| dest_y = s->current_picture.data[0] + (mb_y * 16* s->linesize ) + mb_x * 16; | |||
| dest_cb = s->current_picture.data[1] + (mb_y * 8 * s->uvlinesize) + mb_x * 8; | |||
| dest_cr = s->current_picture.data[2] + (mb_y * 8 * s->uvlinesize) + mb_x * 8; | |||
| } | |||
| if (s->interlaced_dct) { | |||
| @@ -1873,12 +1889,12 @@ void MPV_decode_mb(MpegEncContext *s, DCTELEM block[6][64]) | |||
| } | |||
| if (s->mv_dir & MV_DIR_FORWARD) { | |||
| MPV_motion(s, dest_y, dest_cb, dest_cr, 0, s->last_picture, op_pix, op_qpix); | |||
| MPV_motion(s, dest_y, dest_cb, dest_cr, 0, s->last_picture.data, op_pix, op_qpix); | |||
| op_pix = s->dsp.avg_pixels_tab; | |||
| op_qpix= s->dsp.avg_qpel_pixels_tab; | |||
| } | |||
| if (s->mv_dir & MV_DIR_BACKWARD) { | |||
| MPV_motion(s, dest_y, dest_cb, dest_cr, 1, s->next_picture, op_pix, op_qpix); | |||
| MPV_motion(s, dest_y, dest_cb, dest_cr, 1, s->next_picture.data, op_pix, op_qpix); | |||
| } | |||
| } | |||
| @@ -2154,13 +2170,13 @@ void ff_draw_horiz_band(MpegEncContext *s){ | |||
| offset = y * s->linesize; | |||
| if(s->pict_type==B_TYPE || (!s->has_b_frames)){ | |||
| src_ptr[0] = s->current_picture[0] + offset; | |||
| src_ptr[1] = s->current_picture[1] + (offset >> 2); | |||
| src_ptr[2] = s->current_picture[2] + (offset >> 2); | |||
| src_ptr[0] = s->current_picture.data[0] + offset; | |||
| src_ptr[1] = s->current_picture.data[1] + (offset >> 2); | |||
| src_ptr[2] = s->current_picture.data[2] + (offset >> 2); | |||
| } else { | |||
| src_ptr[0] = s->last_picture[0] + offset; | |||
| src_ptr[1] = s->last_picture[1] + (offset >> 2); | |||
| src_ptr[2] = s->last_picture[2] + (offset >> 2); | |||
| 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(); | |||
| @@ -2180,7 +2196,7 @@ static void encode_mb(MpegEncContext *s, int motion_x, int motion_y) | |||
| for(i=0; i<6; i++) skip_dct[i]=0; | |||
| if(s->adaptive_quant){ | |||
| s->dquant= s->qscale_table[mb_x + mb_y*s->mb_width] - s->qscale; | |||
| s->dquant= s->current_picture.qscale_table[mb_x + mb_y*s->mb_width] - s->qscale; | |||
| if(s->out_format==FMT_H263){ | |||
| if (s->dquant> 2) s->dquant= 2; | |||
| @@ -2206,7 +2222,7 @@ static void encode_mb(MpegEncContext *s, int motion_x, int motion_y) | |||
| int emu=0; | |||
| wrap_y = s->linesize; | |||
| ptr = s->new_picture[0] + (mb_y * 16 * wrap_y) + mb_x * 16; | |||
| ptr = s->new_picture.data[0] + (mb_y * 16 * wrap_y) + mb_x * 16; | |||
| if(mb_x*16+16 > s->width || mb_y*16+16 > s->height){ | |||
| emulated_edge_mc(s, ptr, wrap_y, 16, 16, mb_x*16, mb_y*16, s->width, s->height); | |||
| @@ -2239,14 +2255,14 @@ static void encode_mb(MpegEncContext *s, int motion_x, int motion_y) | |||
| skip_dct[5]= 1; | |||
| }else{ | |||
| int wrap_c = s->uvlinesize; | |||
| ptr = s->new_picture[1] + (mb_y * 8 * wrap_c) + mb_x * 8; | |||
| ptr = s->new_picture.data[1] + (mb_y * 8 * wrap_c) + mb_x * 8; | |||
| if(emu){ | |||
| emulated_edge_mc(s, ptr, wrap_c, 8, 8, mb_x*8, mb_y*8, s->width>>1, s->height>>1); | |||
| ptr= s->edge_emu_buffer; | |||
| } | |||
| s->dsp.get_pixels(s->block[4], ptr, wrap_c); | |||
| ptr = s->new_picture[2] + (mb_y * 8 * wrap_c) + mb_x * 8; | |||
| ptr = s->new_picture.data[2] + (mb_y * 8 * wrap_c) + mb_x * 8; | |||
| if(emu){ | |||
| emulated_edge_mc(s, ptr, wrap_c, 8, 8, mb_x*8, mb_y*8, s->width>>1, s->height>>1); | |||
| ptr= s->edge_emu_buffer; | |||
| @@ -2261,14 +2277,14 @@ static void encode_mb(MpegEncContext *s, int motion_x, int motion_y) | |||
| int wrap_y, wrap_c; | |||
| int emu=0; | |||
| dest_y = s->current_picture[0] + (mb_y * 16 * s->linesize ) + mb_x * 16; | |||
| dest_cb = s->current_picture[1] + (mb_y * 8 * (s->uvlinesize)) + mb_x * 8; | |||
| dest_cr = s->current_picture[2] + (mb_y * 8 * (s->uvlinesize)) + mb_x * 8; | |||
| dest_y = s->current_picture.data[0] + (mb_y * 16 * s->linesize ) + mb_x * 16; | |||
| dest_cb = s->current_picture.data[1] + (mb_y * 8 * (s->uvlinesize)) + mb_x * 8; | |||
| dest_cr = s->current_picture.data[2] + (mb_y * 8 * (s->uvlinesize)) + mb_x * 8; | |||
| wrap_y = s->linesize; | |||
| wrap_c = s->uvlinesize; | |||
| ptr_y = s->new_picture[0] + (mb_y * 16 * wrap_y) + mb_x * 16; | |||
| ptr_cb = s->new_picture[1] + (mb_y * 8 * wrap_c) + mb_x * 8; | |||
| ptr_cr = s->new_picture[2] + (mb_y * 8 * wrap_c) + mb_x * 8; | |||
| ptr_y = s->new_picture.data[0] + (mb_y * 16 * wrap_y) + mb_x * 16; | |||
| ptr_cb = s->new_picture.data[1] + (mb_y * 8 * wrap_c) + mb_x * 8; | |||
| ptr_cr = s->new_picture.data[2] + (mb_y * 8 * wrap_c) + mb_x * 8; | |||
| if ((!s->no_rounding) || s->pict_type==B_TYPE){ | |||
| op_pix = s->dsp.put_pixels_tab; | |||
| @@ -2279,12 +2295,12 @@ static void encode_mb(MpegEncContext *s, int motion_x, int motion_y) | |||
| } | |||
| if (s->mv_dir & MV_DIR_FORWARD) { | |||
| MPV_motion(s, dest_y, dest_cb, dest_cr, 0, s->last_picture, op_pix, op_qpix); | |||
| MPV_motion(s, dest_y, dest_cb, dest_cr, 0, s->last_picture.data, op_pix, op_qpix); | |||
| op_pix = s->dsp.avg_pixels_tab; | |||
| op_qpix= s->dsp.avg_qpel_pixels_tab; | |||
| } | |||
| if (s->mv_dir & MV_DIR_BACKWARD) { | |||
| MPV_motion(s, dest_y, dest_cb, dest_cr, 1, s->next_picture, op_pix, op_qpix); | |||
| MPV_motion(s, dest_y, dest_cb, dest_cr, 1, s->next_picture.data, op_pix, op_qpix); | |||
| } | |||
| if(mb_x*16+16 > s->width || mb_y*16+16 > s->height){ | |||
| @@ -2330,9 +2346,8 @@ static void encode_mb(MpegEncContext *s, int motion_x, int motion_y) | |||
| } | |||
| s->dsp.diff_pixels(s->block[5], ptr_cr, dest_cr, wrap_c); | |||
| } | |||
| /* pre quantization */ | |||
| if(s->mc_mb_var[s->mb_width*mb_y+ mb_x]<2*s->qscale*s->qscale){ | |||
| if(s->current_picture.mc_mb_var[s->mb_width*mb_y+ mb_x]<2*s->qscale*s->qscale){ | |||
| //FIXME optimize | |||
| if(s->dsp.pix_abs8x8(ptr_y , dest_y , wrap_y) < 20*s->qscale) skip_dct[0]= 1; | |||
| if(s->dsp.pix_abs8x8(ptr_y + 8, dest_y + 8, wrap_y) < 20*s->qscale) skip_dct[1]= 1; | |||
| @@ -2557,8 +2572,8 @@ static void encode_picture(MpegEncContext *s, int picture_number) | |||
| s->block_wrap[5]= s->mb_width + 2; | |||
| /* Reset the average MB variance */ | |||
| s->mb_var_sum = 0; | |||
| s->mc_mb_var_sum = 0; | |||
| s->current_picture.mb_var_sum = 0; | |||
| s->current_picture.mc_mb_var_sum = 0; | |||
| /* we need to initialize some time vars before we can encode b-frames */ | |||
| if (s->h263_pred && !s->h263_msmpeg4) | |||
| @@ -2604,15 +2619,15 @@ static void encode_picture(MpegEncContext *s, int picture_number) | |||
| for(mb_x=0; mb_x < s->mb_width; mb_x++) { | |||
| int xx = mb_x * 16; | |||
| int yy = mb_y * 16; | |||
| uint8_t *pix = s->new_picture[0] + (yy * s->linesize) + xx; | |||
| uint8_t *pix = s->new_picture.data[0] + (yy * s->linesize) + xx; | |||
| int varc; | |||
| int sum = s->dsp.pix_sum(pix, s->linesize); | |||
| varc = (s->dsp.pix_norm1(pix, s->linesize) - (((unsigned)(sum*sum))>>8) + 500 + 128)>>8; | |||
| s->mb_var [s->mb_width * mb_y + mb_x] = varc; | |||
| s->mb_mean[s->mb_width * mb_y + mb_x] = (sum+128)>>8; | |||
| s->mb_var_sum += varc; | |||
| s->current_picture.mb_var [s->mb_width * mb_y + mb_x] = varc; | |||
| s->current_picture.mb_mean[s->mb_width * mb_y + mb_x] = (sum+128)>>8; | |||
| s->current_picture.mb_var_sum += varc; | |||
| } | |||
| } | |||
| } | |||
| @@ -2622,13 +2637,9 @@ static void encode_picture(MpegEncContext *s, int picture_number) | |||
| if(s->scene_change_score > 0 && s->pict_type == P_TYPE){ | |||
| s->pict_type= I_TYPE; | |||
| memset(s->mb_type , MB_TYPE_INTRA, sizeof(UINT8)*s->mb_width*s->mb_height); | |||
| if(s->max_b_frames==0){ | |||
| s->input_pict_type= I_TYPE; | |||
| s->input_picture_in_gop_number=0; | |||
| } | |||
| //printf("Scene change detected, encoding as I Frame %d %d\n", s->mb_var_sum, s->mc_mb_var_sum); | |||
| //printf("Scene change detected, encoding as I Frame %d %d\n", s->current_picture.mb_var_sum, s->current_picture.mc_mb_var_sum); | |||
| } | |||
| if(s->pict_type==P_TYPE || s->pict_type==S_TYPE) | |||
| s->f_code= ff_get_best_fcode(s, s->p_mv_table, MB_TYPE_INTER); | |||
| ff_fix_long_p_mvs(s); | |||
| @@ -2643,7 +2654,7 @@ static void encode_picture(MpegEncContext *s, int picture_number) | |||
| } | |||
| if (s->fixed_qscale) | |||
| s->frame_qscale = s->avctx->quality; | |||
| s->frame_qscale = s->current_picture.quality; | |||
| else | |||
| s->frame_qscale = ff_rate_estimate_qscale(s); | |||
| @@ -2658,7 +2669,7 @@ static void encode_picture(MpegEncContext *s, int picture_number) | |||
| break; | |||
| } | |||
| s->qscale= s->qscale_table[0]; | |||
| s->qscale= s->current_picture.qscale_table[0]; | |||
| }else | |||
| s->qscale= (int)(s->frame_qscale + 0.5); | |||
| @@ -2673,6 +2684,13 @@ static void encode_picture(MpegEncContext *s, int picture_number) | |||
| convert_matrix(s, s->q_intra_matrix, s->q_intra_matrix16, | |||
| s->q_intra_matrix16_bias, s->intra_matrix, s->intra_quant_bias, 8, 8); | |||
| } | |||
| //FIXME var duplication | |||
| s->current_picture.key_frame= s->pict_type == I_TYPE; | |||
| s->current_picture.pict_type= s->pict_type; | |||
| if(s->current_picture.key_frame) | |||
| s->picture_in_gop_number=0; | |||
| s->last_bits= get_bit_count(&s->pb); | |||
| switch(s->out_format) { | |||
| @@ -28,6 +28,8 @@ enum OutputFormat { | |||
| FMT_MJPEG, | |||
| }; | |||
| #define EDGE_WIDTH 16 | |||
| #define MPEG_BUF_SIZE (16 * 1024) | |||
| #define QMAT_SHIFT_MMX 16 | |||
| @@ -35,7 +37,8 @@ enum OutputFormat { | |||
| #define MAX_FCODE 7 | |||
| #define MAX_MV 2048 | |||
| #define REORDER_BUFFER_SIZE (FF_MAX_B_FRAMES+2) | |||
| #define MAX_PICTURE_COUNT 7 | |||
| #define ME_MAP_SIZE 64 | |||
| #define ME_MAP_SHIFT 3 | |||
| @@ -90,14 +93,6 @@ typedef struct RateControlContext{ | |||
| int last_non_b_pict_type; | |||
| }RateControlContext; | |||
| typedef struct ReorderBuffer{ | |||
| UINT8 *picture[3]; | |||
| int pict_type; | |||
| int qscale; | |||
| int force_type; | |||
| int picture_number; | |||
| int picture_in_gop_number; | |||
| } ReorderBuffer; | |||
| typedef struct ScanTable{ | |||
| const UINT8 *scantable; | |||
| @@ -109,6 +104,16 @@ typedef struct ScanTable{ | |||
| #endif | |||
| } ScanTable; | |||
| typedef struct Picture{ | |||
| FF_COMMON_PICTURE | |||
| int mb_var_sum; /* sum of MB variance for current frame */ | |||
| int mc_mb_var_sum; /* motion compensated MB variance for current frame */ | |||
| uint16_t *mb_var; /* Table for MB variances */ | |||
| uint16_t *mc_mb_var; /* Table for motion compensated MB variances */ | |||
| uint8_t *mb_mean; /* Table for MB luminance */ | |||
| } Picture; | |||
| typedef struct ParseContext{ | |||
| UINT8 *buffer; | |||
| int index; | |||
| @@ -145,7 +150,6 @@ typedef struct MpegEncContext { | |||
| int max_qdiff; /* max qscale difference between frames */ | |||
| int encoding; /* true if we are encoding (vs decoding) */ | |||
| int flags; /* AVCodecContext.flags (HQ, MV4, ...) */ | |||
| int force_input_type;/* 0= no force, otherwise I_TYPE, P_TYPE, ... */ | |||
| int max_b_frames; /* max number of b-frames for encoding */ | |||
| int b_frame_strategy; | |||
| int luma_elim_threshold; | |||
| @@ -160,10 +164,7 @@ typedef struct MpegEncContext { | |||
| /* sequence parameters */ | |||
| int context_initialized; | |||
| int input_picture_number; | |||
| int input_picture_in_gop_number; /* 0-> first pic in gop, ... */ | |||
| int picture_number; | |||
| int fake_picture_number; /* picture number at the bitstream frame rate */ | |||
| int gop_picture_number; /* index of the first picture of a GOP based on fake_pic_num & mpeg1 specific */ | |||
| int picture_in_gop_number; /* 0-> first pic in gop, ... */ | |||
| int b_frames_since_non_b; /* used for encoding, relative to not yet reordered input */ | |||
| int mb_width, mb_height; /* number of MBs horizontally & vertically */ | |||
| @@ -171,20 +172,13 @@ typedef struct MpegEncContext { | |||
| int mb_num; /* number of MBs of a picture */ | |||
| int linesize; /* line size, in bytes, may be different from width */ | |||
| int uvlinesize; /* line size, for chroma in bytes, may be different from width */ | |||
| UINT8 *new_picture[3]; /* picture to be compressed */ | |||
| UINT8 *picture_buffer[REORDER_BUFFER_SIZE][3]; /* internal buffers used for reordering of input pictures */ | |||
| int picture_buffer_index; | |||
| ReorderBuffer coded_order[REORDER_BUFFER_SIZE]; | |||
| UINT8 *last_picture[3]; /* previous picture */ | |||
| UINT8 *last_picture_base[3]; /* real start of the picture */ | |||
| UINT8 *next_picture[3]; /* previous picture (for bidir pred) */ | |||
| UINT8 *next_picture_base[3]; /* real start of the picture */ | |||
| UINT8 *aux_picture[3]; /* aux picture (for B frames only) */ | |||
| UINT8 *aux_picture_base[3]; /* real start of the picture */ | |||
| UINT8 *current_picture[3]; /* buffer to store the decompressed current picture */ | |||
| void *last_dr_opaque; | |||
| void *next_dr_opaque; | |||
| int ip_buffer_count; /* number of buffers, currently only >2 if dr1 is used */ | |||
| Picture picture[MAX_PICTURE_COUNT]; /* main picture buffer */ | |||
| Picture *input_picture[MAX_PICTURE_COUNT]; /* next pictures on display order for encoding*/ | |||
| Picture *reordered_input_picture[MAX_PICTURE_COUNT]; /* pointer to the next pictures in codedorder for encoding*/ | |||
| Picture last_picture; /* previous picture */ | |||
| Picture next_picture; /* previous picture (for bidir pred) */ | |||
| Picture new_picture; /* source picture for encoding */ | |||
| Picture current_picture; /* buffer to store the decompressed current picture */ | |||
| int num_available_buffers; /* is 0 at the start & after seeking, after the first I frame its 1 after next I/P 2 */ | |||
| int last_dc[3]; /* last DC values for MPEG1 */ | |||
| INT16 *dc_val[3]; /* used for mpeg4 DC prediction, all 3 arrays must be continuous */ | |||
| @@ -200,17 +194,10 @@ typedef struct MpegEncContext { | |||
| UINT8 *mbintra_table; /* used to avoid setting {ac, dc, cbp}-pred stuff to zero on inter MB decoding */ | |||
| UINT8 *cbp_table; /* used to store cbp, ac_pred for partitioned decoding */ | |||
| UINT8 *pred_dir_table; /* used to store pred_dir for partitioned decoding */ | |||
| INT8 *qscale_table; /* used to store qscale */ | |||
| INT8 *aux_qscale_table; | |||
| INT8 *next_qscale_table; | |||
| INT8 *last_qscale_table; //FIXME move these into some picture struct (MpegEncContext.aux.qscale_table[]) | |||
| UINT8 *edge_emu_buffer; | |||
| int input_qscale; /* qscale prior to reordering of frames */ | |||
| int input_pict_type; /* pict_type prior to reordering of frames */ | |||
| int force_type; /* 0= no force, otherwise I_TYPE, P_TYPE, ... */ | |||
| int qscale; /* QP */ | |||
| float frame_qscale; /* qscale from the frame level rc */ | |||
| float frame_qscale; /* qscale from the frame level rc FIXME remove*/ | |||
| int adaptive_quant; /* use adaptive quantization */ | |||
| int dquant; /* qscale difference to prev qscale */ | |||
| int pict_type; /* I_TYPE, P_TYPE, B_TYPE, ... */ | |||
| @@ -272,9 +259,6 @@ typedef struct MpegEncContext { | |||
| int mb_x, mb_y; | |||
| int mb_incr; | |||
| int mb_intra; | |||
| UINT16 *mb_var; /* Table for MB variances */ | |||
| UINT16 *mc_mb_var; /* Table for motion compensated MB variances */ | |||
| UINT8 *mb_mean; /* Table for MB luminance */ | |||
| UINT8 *mb_type; /* Table for MB type */ | |||
| #define MB_TYPE_INTRA 0x01 | |||
| #define MB_TYPE_INTER 0x02 | |||
| @@ -325,8 +309,6 @@ typedef struct MpegEncContext { | |||
| /* bit rate control */ | |||
| int I_frame_bits; //FIXME used in mpeg12 ... | |||
| int mb_var_sum; /* sum of MB variance for current frame */ | |||
| int mc_mb_var_sum; /* motion compensated MB variance for current frame */ | |||
| INT64 wanted_bits; | |||
| INT64 total_bits; | |||
| int frame_bits; /* bits used for the current frame */ | |||
| @@ -476,6 +458,10 @@ typedef struct MpegEncContext { | |||
| /* decompression specific */ | |||
| GetBitContext gb; | |||
| /* Mpeg1 specific */ | |||
| int fake_picture_number; /* picture number at the bitstream frame rate */ | |||
| int gop_picture_number; /* index of the first picture of a GOP based on fake_pic_num & mpeg1 specific */ | |||
| /* MPEG2 specific - I wish I had not to support this mess. */ | |||
| int progressive_sequence; | |||
| int mpeg_f_code[2][2]; | |||
| @@ -498,7 +484,6 @@ typedef struct MpegEncContext { | |||
| int mpeg2; | |||
| int full_pel[2]; | |||
| int interlaced_dct; | |||
| int last_qscale; | |||
| int first_slice; | |||
| /* RTP specific */ | |||
| @@ -759,10 +759,10 @@ static inline int msmpeg4_pred_dc(MpegEncContext * s, int n, | |||
| }else{ | |||
| if(n<4){ | |||
| wrap= s->linesize; | |||
| dest= s->current_picture[0] + (((n>>1) + 2*s->mb_y) * 8* wrap ) + ((n&1) + 2*s->mb_x) * 8; | |||
| dest= s->current_picture.data[0] + (((n>>1) + 2*s->mb_y) * 8* wrap ) + ((n&1) + 2*s->mb_x) * 8; | |||
| }else{ | |||
| wrap= s->uvlinesize; | |||
| dest= s->current_picture[n-3] + (s->mb_y * 8 * wrap) + s->mb_x * 8; | |||
| dest= s->current_picture.data[n-3] + (s->mb_y * 8 * wrap) + s->mb_x * 8; | |||
| } | |||
| if(s->mb_x==0) a= (1024 + (scale>>1))/scale; | |||
| else a= get_dc(dest-8, wrap, scale*8); | |||
| @@ -41,7 +41,7 @@ void ff_write_pass1_stats(MpegEncContext *s){ | |||
| sprintf(s->avctx->stats_out, "in:%d out:%d type:%d q:%f itex:%d ptex:%d mv:%d misc:%d fcode:%d bcode:%d mc-var:%d var:%d icount:%d;\n", | |||
| s->picture_number, s->input_picture_number - s->max_b_frames, s->pict_type, | |||
| s->frame_qscale, s->i_tex_bits, s->p_tex_bits, s->mv_bits, s->misc_bits, | |||
| s->f_code, s->b_code, s->mc_mb_var_sum, s->mb_var_sum, s->i_count); | |||
| s->f_code, s->b_code, s->current_picture.mc_mb_var_sum, s->current_picture.mb_var_sum, s->i_count); | |||
| } | |||
| int ff_rate_control_init(MpegEncContext *s) | |||
| @@ -475,11 +475,12 @@ static void adaptive_quantization(MpegEncContext *s, double q){ | |||
| float bits_tab[s->mb_num]; | |||
| const int qmin= 2; //s->avctx->mb_qmin; | |||
| const int qmax= 31; //s->avctx->mb_qmax; | |||
| Picture * const pic= &s->current_picture; | |||
| for(i=0; i<s->mb_num; i++){ | |||
| float temp_cplx= sqrt(s->mc_mb_var[i]); | |||
| float spat_cplx= sqrt(s->mb_var[i]); | |||
| const int lumi= s->mb_mean[i]; | |||
| float temp_cplx= sqrt(pic->mc_mb_var[i]); | |||
| float spat_cplx= sqrt(pic->mb_var[i]); | |||
| const int lumi= pic->mb_mean[i]; | |||
| float bits, cplx, factor; | |||
| if(spat_cplx < q/3) spat_cplx= q/3; //FIXME finetune | |||
| @@ -533,8 +534,8 @@ static void adaptive_quantization(MpegEncContext *s, double q){ | |||
| newq*= bits_sum/cplx_sum; | |||
| } | |||
| if(i && ABS(s->qscale_table[i-1] - newq)<0.75) | |||
| intq= s->qscale_table[i-1]; | |||
| if(i && ABS(pic->qscale_table[i-1] - newq)<0.75) | |||
| intq= pic->qscale_table[i-1]; | |||
| else | |||
| intq= (int)(newq + 0.5); | |||
| @@ -542,7 +543,7 @@ static void adaptive_quantization(MpegEncContext *s, double q){ | |||
| else if(intq < qmin) intq= qmin; | |||
| //if(i%s->mb_width==0) printf("\n"); | |||
| //printf("%2d%3d ", intq, ff_sqrt(s->mc_mb_var[i])); | |||
| s->qscale_table[i]= intq; | |||
| pic->qscale_table[i]= intq; | |||
| } | |||
| } | |||
| @@ -562,6 +563,7 @@ float ff_rate_estimate_qscale(MpegEncContext *s) | |||
| double rate_factor; | |||
| int var; | |||
| const int pict_type= s->pict_type; | |||
| Picture * const pic= &s->current_picture; | |||
| emms_c(); | |||
| get_qminmax(&qmin, &qmax, s, pict_type); | |||
| @@ -588,7 +590,7 @@ float ff_rate_estimate_qscale(MpegEncContext *s) | |||
| br_compensation= (s->bit_rate_tolerance - diff)/s->bit_rate_tolerance; | |||
| if(br_compensation<=0.0) br_compensation=0.001; | |||
| var= pict_type == I_TYPE ? s->mb_var_sum : s->mc_mb_var_sum; | |||
| var= pict_type == I_TYPE ? pic->mb_var_sum : pic->mc_mb_var_sum; | |||
| if(s->flags&CODEC_FLAG_PASS2){ | |||
| if(pict_type!=I_TYPE) | |||
| @@ -599,8 +601,8 @@ float ff_rate_estimate_qscale(MpegEncContext *s) | |||
| }else{ | |||
| rce->pict_type= | |||
| rce->new_pict_type= pict_type; | |||
| rce->mc_mb_var_sum= s->mc_mb_var_sum; | |||
| rce->mb_var_sum = s-> mb_var_sum; | |||
| rce->mc_mb_var_sum= pic->mc_mb_var_sum; | |||
| rce->mb_var_sum = pic-> mb_var_sum; | |||
| rce->qscale = 2; | |||
| rce->f_code = s->f_code; | |||
| rce->b_code = s->b_code; | |||
| @@ -663,10 +665,8 @@ float ff_rate_estimate_qscale(MpegEncContext *s) | |||
| else if(q>qmax) q=qmax; | |||
| // printf("%f %d %d %d\n", q, picture_number, (int)wanted_bits, (int)s->total_bits); | |||
| //printf("%f %f %f\n", q, br_compensation, short_term_q); | |||
| //printf("q:%d diff:%d comp:%f st_q:%f last_size:%d type:%d\n", qscale, (int)diff, br_compensation, | |||
| //printf("diff:%d comp:%f st_q:%f last_size:%d type:%d\n", (int)diff, br_compensation, | |||
| // short_term_q, s->frame_bits, pict_type); | |||
| //printf("%d %d\n", s->bit_rate, (int)fps); | |||
| @@ -676,8 +676,16 @@ float ff_rate_estimate_qscale(MpegEncContext *s) | |||
| q= (int)(q + 0.5); | |||
| rcc->last_qscale= q; | |||
| rcc->last_mc_mb_var_sum= s->mc_mb_var_sum; | |||
| rcc->last_mb_var_sum= s->mb_var_sum; | |||
| rcc->last_mc_mb_var_sum= pic->mc_mb_var_sum; | |||
| rcc->last_mb_var_sum= pic->mb_var_sum; | |||
| #if 0 | |||
| { | |||
| static int mvsum=0, texsum=0; | |||
| mvsum += s->mv_bits; | |||
| texsum += s->i_tex_bits + s->p_tex_bits; | |||
| printf("%d %d//\n\n", mvsum, texsum); | |||
| } | |||
| #endif | |||
| return q; | |||
| } | |||
| @@ -472,7 +472,7 @@ static int rv10_decode_frame(AVCodecContext *avctx, | |||
| { | |||
| MpegEncContext *s = avctx->priv_data; | |||
| int i; | |||
| AVPicture *pict = data; | |||
| AVVideoFrame *pict = data; | |||
| #ifdef DEBUG | |||
| printf("*****frame %d size=%d\n", avctx->frame_number, buf_size); | |||
| @@ -505,15 +505,9 @@ static int rv10_decode_frame(AVCodecContext *avctx, | |||
| if(s->mb_y>=s->mb_height){ | |||
| MPV_frame_end(s); | |||
| pict->data[0] = s->current_picture[0]; | |||
| pict->data[1] = s->current_picture[1]; | |||
| pict->data[2] = s->current_picture[2]; | |||
| pict->linesize[0] = s->linesize; | |||
| pict->linesize[1] = s->uvlinesize; | |||
| pict->linesize[2] = s->uvlinesize; | |||
| *pict= *(AVVideoFrame*)&s->current_picture; | |||
| avctx->quality = s->qscale; | |||
| *data_size = sizeof(AVPicture); | |||
| *data_size = sizeof(AVVideoFrame); | |||
| }else{ | |||
| *data_size = 0; | |||
| } | |||
| @@ -1063,7 +1063,7 @@ static int svq1_decode_frame(AVCodecContext *avctx, | |||
| MpegEncContext *s=avctx->priv_data; | |||
| uint8_t *current, *previous; | |||
| int result, i, x, y, width, height; | |||
| AVPicture *pict = data; | |||
| AVVideoFrame *pict = data; | |||
| /* initialize bit buffer */ | |||
| init_get_bits(&s->gb,buf,buf_size); | |||
| @@ -1084,9 +1084,6 @@ static int svq1_decode_frame(AVCodecContext *avctx, | |||
| } | |||
| result = svq1_decode_frame_header (&s->gb, s); | |||
| if(MPV_frame_start(s, avctx) < 0) | |||
| return -1; | |||
| if (result != 0) | |||
| { | |||
| @@ -1098,6 +1095,9 @@ static int svq1_decode_frame(AVCodecContext *avctx, | |||
| if(avctx->hurry_up && s->pict_type==B_TYPE) return buf_size; | |||
| if(MPV_frame_start(s, avctx) < 0) | |||
| return -1; | |||
| /* decode y, u and v components */ | |||
| for (i=0; i < 3; i++) { | |||
| int linesize; | |||
| @@ -1112,12 +1112,12 @@ static int svq1_decode_frame(AVCodecContext *avctx, | |||
| linesize= s->uvlinesize; | |||
| } | |||
| current = s->current_picture[i]; | |||
| current = s->current_picture.data[i]; | |||
| if(s->pict_type==B_TYPE){ | |||
| previous = s->next_picture[i]; | |||
| previous = s->next_picture.data[i]; | |||
| }else{ | |||
| previous = s->last_picture[i]; | |||
| previous = s->last_picture.data[i]; | |||
| } | |||
| if (s->pict_type == I_TYPE) { | |||
| @@ -1159,12 +1159,14 @@ static int svq1_decode_frame(AVCodecContext *avctx, | |||
| current += 16*linesize; | |||
| } | |||
| } | |||
| pict->data[i] = s->current_picture[i]; | |||
| pict->linesize[i] = linesize; | |||
| } | |||
| *pict = *(AVVideoFrame*)&s->current_picture; | |||
| *data_size=sizeof(AVPicture); | |||
| MPV_frame_end(s); | |||
| *data_size=sizeof(AVVideoFrame); | |||
| return buf_size; | |||
| } | |||
| @@ -1176,7 +1178,6 @@ static int svq1_decode_init(AVCodecContext *avctx) | |||
| s->width = (avctx->width+3)&~3; | |||
| s->height = (avctx->height+3)&~3; | |||
| s->codec_id= avctx->codec->id; | |||
| avctx->mbskip_table= s->mbskip_table; | |||
| avctx->pix_fmt = PIX_FMT_YUV410P; | |||
| avctx->has_b_frames= s->has_b_frames=1; // not true, but DP frames and these behave like unidirectional b frames | |||
| s->flags= avctx->flags; | |||
| @@ -86,6 +86,123 @@ void register_avcodec(AVCodec *format) | |||
| format->next = NULL; | |||
| } | |||
| void avcodec_get_chroma_sub_sample(int fmt, int *h_shift, int *v_shift){ | |||
| switch(fmt){ | |||
| case PIX_FMT_YUV410P: | |||
| *h_shift=2; | |||
| *v_shift=2; | |||
| break; | |||
| case PIX_FMT_YUV420P: | |||
| *h_shift=1; | |||
| *v_shift=1; | |||
| break; | |||
| case PIX_FMT_YUV411P: | |||
| *h_shift=2; | |||
| *v_shift=0; | |||
| break; | |||
| case PIX_FMT_YUV422P: | |||
| case PIX_FMT_YUV422: | |||
| *h_shift=1; | |||
| *v_shift=0; | |||
| break; | |||
| default: //RGB/... | |||
| *h_shift=0; | |||
| *v_shift=0; | |||
| break; | |||
| } | |||
| } | |||
| typedef struct DefaultPicOpaque{ | |||
| int last_pic_num; | |||
| uint8_t *data[4]; | |||
| }DefaultPicOpaque; | |||
| int avcodec_default_get_buffer(AVCodecContext *s, AVVideoFrame *pic){ | |||
| int i; | |||
| const int width = s->width; | |||
| const int height= s->height; | |||
| DefaultPicOpaque *opaque; | |||
| if(pic->opaque){ | |||
| opaque= (DefaultPicOpaque *)pic->opaque; | |||
| for(i=0; i<3; i++) | |||
| pic->data[i]= opaque->data[i]; | |||
| // printf("get_buffer %X coded_pic_num:%d last:%d\n", pic->opaque, pic->coded_picture_number, opaque->last_pic_num); | |||
| pic->age= pic->coded_picture_number - opaque->last_pic_num; | |||
| opaque->last_pic_num= pic->coded_picture_number; | |||
| //printf("age: %d %d %d\n", pic->age, c->picture_number, pic->coded_picture_number); | |||
| }else{ | |||
| int align, h_chroma_shift, v_chroma_shift; | |||
| int w, h, pixel_size; | |||
| avcodec_get_chroma_sub_sample(s->pix_fmt, &h_chroma_shift, &v_chroma_shift); | |||
| switch(s->pix_fmt){ | |||
| case PIX_FMT_YUV422: | |||
| pixel_size=2; | |||
| break; | |||
| case PIX_FMT_RGB24: | |||
| case PIX_FMT_BGR24: | |||
| pixel_size=3; | |||
| break; | |||
| case PIX_FMT_BGRA32: | |||
| case PIX_FMT_RGBA32: | |||
| pixel_size=4; | |||
| break; | |||
| default: | |||
| pixel_size=1; | |||
| } | |||
| if(s->codec_id==CODEC_ID_SVQ1) align=63; | |||
| else align=15; | |||
| w= (width +align)&~align; | |||
| h= (height+align)&~align; | |||
| if(!(s->flags&CODEC_FLAG_EMU_EDGE)){ | |||
| w+= EDGE_WIDTH*2; | |||
| h+= EDGE_WIDTH*2; | |||
| } | |||
| opaque= av_mallocz(sizeof(DefaultPicOpaque)); | |||
| if(opaque==NULL) return -1; | |||
| pic->opaque= opaque; | |||
| opaque->last_pic_num= -256*256*256*64; | |||
| for(i=0; i<3; i++){ | |||
| int h_shift= i==0 ? 0 : h_chroma_shift; | |||
| int v_shift= i==0 ? 0 : v_chroma_shift; | |||
| pic->linesize[i]= pixel_size*w>>h_shift; | |||
| pic->base[i]= av_mallocz((pic->linesize[i]*h>>v_shift)+16); //FIXME 16 | |||
| if(pic->base[i]==NULL) return -1; | |||
| memset(pic->base[i], 128, pic->linesize[i]*h>>v_shift); | |||
| if(s->flags&CODEC_FLAG_EMU_EDGE) | |||
| pic->data[i] = pic->base[i]; | |||
| else | |||
| pic->data[i] = pic->base[i] + (pic->linesize[i]*EDGE_WIDTH>>v_shift) + (EDGE_WIDTH>>h_shift); | |||
| opaque->data[i]= pic->data[i]; | |||
| } | |||
| pic->age= 256*256*256*64; | |||
| } | |||
| return 0; | |||
| } | |||
| void avcodec_default_release_buffer(AVCodecContext *s, AVVideoFrame *pic){ | |||
| int i; | |||
| for(i=0; i<3; i++) | |||
| pic->data[i]=NULL; | |||
| //printf("R%X\n", pic->opaque); | |||
| } | |||
| void avcodec_get_context_defaults(AVCodecContext *s){ | |||
| s->bit_rate= 800*1000; | |||
| s->bit_rate_tolerance= s->bit_rate*10; | |||
| @@ -104,6 +221,8 @@ void avcodec_get_context_defaults(AVCodecContext *s){ | |||
| s->frame_rate = 25 * FRAME_RATE_BASE; | |||
| s->gop_size= 50; | |||
| s->me_method= ME_EPZS; | |||
| s->get_buffer= avcodec_default_get_buffer; | |||
| s->release_buffer= avcodec_default_release_buffer; | |||
| } | |||
| /** | |||
| @@ -120,6 +239,16 @@ AVCodecContext *avcodec_alloc_context(void){ | |||
| return avctx; | |||
| } | |||
| /** | |||
| * allocates a AVPicture and set it to defaults. | |||
| * this can be deallocated by simply calling free() | |||
| */ | |||
| AVVideoFrame *avcodec_alloc_picture(void){ | |||
| AVVideoFrame *pic= av_mallocz(sizeof(AVVideoFrame)); | |||
| return pic; | |||
| } | |||
| int avcodec_open(AVCodecContext *avctx, AVCodec *codec) | |||
| { | |||
| int ret; | |||
| @@ -152,7 +281,7 @@ int avcodec_encode_audio(AVCodecContext *avctx, UINT8 *buf, int buf_size, | |||
| } | |||
| int avcodec_encode_video(AVCodecContext *avctx, UINT8 *buf, int buf_size, | |||
| const AVPicture *pict) | |||
| const AVVideoFrame *pict) | |||
| { | |||
| int ret; | |||
| @@ -167,17 +296,17 @@ int avcodec_encode_video(AVCodecContext *avctx, UINT8 *buf, int buf_size, | |||
| /* decode a frame. return -1 if error, otherwise return the number of | |||
| bytes used. If no frame could be decompressed, *got_picture_ptr is | |||
| zero. Otherwise, it is non zero */ | |||
| int avcodec_decode_video(AVCodecContext *avctx, AVPicture *picture, | |||
| int avcodec_decode_video(AVCodecContext *avctx, AVVideoFrame *picture, | |||
| int *got_picture_ptr, | |||
| UINT8 *buf, int buf_size) | |||
| { | |||
| int ret; | |||
| ret = avctx->codec->decode(avctx, picture, got_picture_ptr, | |||
| buf, buf_size); | |||
| emms_c(); //needed to avoid a emms_c() call before every return; | |||
| if (*got_picture_ptr) | |||
| avctx->frame_number++; | |||
| return ret; | |||
| @@ -556,7 +556,7 @@ static void put_frame_header(AVFormatContext *s, ASFStream *stream, int timestam | |||
| int val; | |||
| val = stream->num; | |||
| if (s->streams[val - 1]->codec.key_frame /* && frag_offset == 0 */) | |||
| if (s->streams[val - 1]->codec.coded_picture->key_frame /* && frag_offset == 0 */) | |||
| val |= 0x80; | |||
| put_byte(pb, val); | |||
| put_byte(pb, stream->seq); | |||
| @@ -793,6 +793,7 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap) | |||
| st = av_mallocz(sizeof(AVStream)); | |||
| if (!st) | |||
| goto fail; | |||
| avcodec_get_context_defaults(&st->codec); | |||
| s->streams[s->nb_streams] = st; | |||
| asf_st = av_mallocz(sizeof(ASFStream)); | |||
| if (!asf_st) | |||
| @@ -143,6 +143,8 @@ static int au_read_header(AVFormatContext *s, | |||
| st = av_malloc(sizeof(AVStream)); | |||
| if (!st) | |||
| return -1; | |||
| avcodec_get_context_defaults(&st->codec); | |||
| s->nb_streams = 1; | |||
| s->streams[0] = st; | |||
| @@ -144,6 +144,9 @@ typedef struct AVStream { | |||
| AVFrac pts; | |||
| /* ffmpeg.c private use */ | |||
| int stream_copy; /* if TRUE, just copy stream */ | |||
| /* quality, as it has been removed from AVCodecContext and put in AVVideoFrame | |||
| * MN:dunno if thats the right place, for it */ | |||
| float quality; | |||
| } AVStream; | |||
| #define MAX_STREAMS 20 | |||
| @@ -103,6 +103,8 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap) | |||
| AVStream *st = av_mallocz(sizeof(AVStream)); | |||
| if (!st) | |||
| goto fail; | |||
| avcodec_get_context_defaults(&st->codec); | |||
| s->streams[i] = st; | |||
| } | |||
| url_fskip(pb, size - 7 * 4); | |||
| @@ -320,7 +320,7 @@ static int avi_write_packet(AVFormatContext *s, int stream_index, | |||
| if (enc->codec_type == CODEC_TYPE_VIDEO) { | |||
| tag[2] = 'd'; | |||
| tag[3] = 'c'; | |||
| flags = enc->key_frame ? 0x10 : 0x00; | |||
| flags = enc->coded_picture->key_frame ? 0x10 : 0x00; | |||
| } else { | |||
| tag[2] = 'w'; | |||
| tag[3] = 'b'; | |||
| @@ -151,7 +151,7 @@ static int ffm_write_header(AVFormatContext *s) | |||
| put_be32(pb, codec->codec_id); | |||
| put_byte(pb, codec->codec_type); | |||
| put_be32(pb, codec->bit_rate); | |||
| put_be32(pb, codec->quality); | |||
| put_be32(pb, st->quality); | |||
| put_be32(pb, codec->flags); | |||
| /* specific info */ | |||
| switch(codec->codec_type) { | |||
| @@ -232,7 +232,7 @@ static int ffm_write_packet(AVFormatContext *s, int stream_index, | |||
| /* packet size & key_frame */ | |||
| header[0] = stream_index; | |||
| header[1] = 0; | |||
| if (st->codec.key_frame) | |||
| if (st->codec.coded_picture->key_frame) | |||
| header[1] |= FLAG_KEY_FRAME; | |||
| header[2] = (size >> 16) & 0xff; | |||
| header[3] = (size >> 8) & 0xff; | |||
| @@ -394,6 +394,7 @@ static int ffm_read_header(AVFormatContext *s, AVFormatParameters *ap) | |||
| st = av_mallocz(sizeof(AVStream)); | |||
| if (!st) | |||
| goto fail; | |||
| avcodec_get_context_defaults(&st->codec); | |||
| s->streams[i] = st; | |||
| fst = av_mallocz(sizeof(FFMStream)); | |||
| if (!fst) | |||
| @@ -405,7 +406,7 @@ static int ffm_read_header(AVFormatContext *s, AVFormatParameters *ap) | |||
| st->codec.codec_id = get_be32(pb); | |||
| st->codec.codec_type = get_byte(pb); /* codec_type */ | |||
| codec->bit_rate = get_be32(pb); | |||
| codec->quality = get_be32(pb); | |||
| st->quality = get_be32(pb); | |||
| codec->flags = get_be32(pb); | |||
| /* specific info */ | |||
| switch(codec->codec_type) { | |||
| @@ -170,6 +170,8 @@ static int jpeg_read_header(AVFormatContext *s1, AVFormatParameters *ap) | |||
| av_free(s); | |||
| return -ENOMEM; | |||
| } | |||
| avcodec_get_context_defaults(&st->codec); | |||
| s1->streams[0] = st; | |||
| s->img_number = 0; | |||
| @@ -352,7 +352,7 @@ static int rm_write_video(AVFormatContext *s, UINT8 *buf, int size) | |||
| RMContext *rm = s->priv_data; | |||
| ByteIOContext *pb = &s->pb; | |||
| StreamInfo *stream = rm->video_stream; | |||
| int key_frame = stream->enc->key_frame; | |||
| int key_frame = stream->enc->coded_picture->key_frame; | |||
| /* XXX: this is incorrect: should be a parameter */ | |||
| @@ -527,6 +527,7 @@ static int rm_read_header(AVFormatContext *s, AVFormatParameters *ap) | |||
| st = av_mallocz(sizeof(AVStream)); | |||
| if (!st) | |||
| goto fail; | |||
| avcodec_get_context_defaults(&st->codec); | |||
| s->streams[s->nb_streams++] = st; | |||
| st->id = get_be16(pb); | |||
| get_be32(pb); /* max bit rate */ | |||
| @@ -482,6 +482,8 @@ static int swf_read_header(AVFormatContext *s, AVFormatParameters *ap) | |||
| st = av_mallocz(sizeof(AVStream)); | |||
| if (!st) | |||
| return -ENOMEM; | |||
| avcodec_get_context_defaults(&st->codec); | |||
| if (v & 0x01) | |||
| st->codec.channels = 2; | |||
| else | |||
| @@ -458,7 +458,7 @@ int av_find_stream_info(AVFormatContext *ic) | |||
| AVCodec *codec; | |||
| AVStream *st; | |||
| AVPacket *pkt; | |||
| AVPicture picture; | |||
| AVVideoFrame picture; | |||
| AVPacketList *pktl=NULL, **ppktl; | |||
| short samples[AVCODEC_MAX_AUDIO_FRAME_SIZE / 2]; | |||
| UINT8 *ptr; | |||
| @@ -694,6 +694,8 @@ AVStream *av_new_stream(AVFormatContext *s, int id) | |||
| st = av_mallocz(sizeof(AVStream)); | |||
| if (!st) | |||
| return NULL; | |||
| avcodec_get_context_defaults(&st->codec); | |||
| st->index = s->nb_streams; | |||
| st->id = id; | |||
| s->streams[s->nb_streams++] = st; | |||