| @@ -90,7 +90,7 @@ AVCodec ff_flv_encoder = { | |||||
| .id = CODEC_ID_FLV1, | .id = CODEC_ID_FLV1, | ||||
| .priv_data_size = sizeof(MpegEncContext), | .priv_data_size = sizeof(MpegEncContext), | ||||
| .init = ff_MPV_encode_init, | .init = ff_MPV_encode_init, | ||||
| .encode = ff_MPV_encode_picture, | |||||
| .encode2 = ff_MPV_encode_picture, | |||||
| .close = ff_MPV_encode_end, | .close = ff_MPV_encode_end, | ||||
| .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, | .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, | ||||
| .long_name= NULL_IF_CONFIG_SMALL("Flash Video (FLV) / Sorenson Spark / Sorenson H.263"), | .long_name= NULL_IF_CONFIG_SMALL("Flash Video (FLV) / Sorenson Spark / Sorenson H.263"), | ||||
| @@ -327,7 +327,7 @@ AVCodec ff_h261_encoder = { | |||||
| .id = CODEC_ID_H261, | .id = CODEC_ID_H261, | ||||
| .priv_data_size = sizeof(H261Context), | .priv_data_size = sizeof(H261Context), | ||||
| .init = ff_MPV_encode_init, | .init = ff_MPV_encode_init, | ||||
| .encode = ff_MPV_encode_picture, | |||||
| .encode2 = ff_MPV_encode_picture, | |||||
| .close = ff_MPV_encode_end, | .close = ff_MPV_encode_end, | ||||
| .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, | .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, | ||||
| .long_name= NULL_IF_CONFIG_SMALL("H.261"), | .long_name= NULL_IF_CONFIG_SMALL("H.261"), | ||||
| @@ -451,7 +451,7 @@ AVCodec ff_mjpeg_encoder = { | |||||
| .id = CODEC_ID_MJPEG, | .id = CODEC_ID_MJPEG, | ||||
| .priv_data_size = sizeof(MpegEncContext), | .priv_data_size = sizeof(MpegEncContext), | ||||
| .init = ff_MPV_encode_init, | .init = ff_MPV_encode_init, | ||||
| .encode = ff_MPV_encode_picture, | |||||
| .encode2 = ff_MPV_encode_picture, | |||||
| .close = ff_MPV_encode_end, | .close = ff_MPV_encode_end, | ||||
| .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUVJ420P, PIX_FMT_YUVJ422P, PIX_FMT_NONE}, | .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUVJ420P, PIX_FMT_YUVJ422P, PIX_FMT_NONE}, | ||||
| .long_name= NULL_IF_CONFIG_SMALL("MJPEG (Motion JPEG)"), | .long_name= NULL_IF_CONFIG_SMALL("MJPEG (Motion JPEG)"), | ||||
| @@ -954,7 +954,7 @@ AVCodec ff_mpeg1video_encoder = { | |||||
| .id = CODEC_ID_MPEG1VIDEO, | .id = CODEC_ID_MPEG1VIDEO, | ||||
| .priv_data_size = sizeof(MpegEncContext), | .priv_data_size = sizeof(MpegEncContext), | ||||
| .init = encode_init, | .init = encode_init, | ||||
| .encode = ff_MPV_encode_picture, | |||||
| .encode2 = ff_MPV_encode_picture, | |||||
| .close = ff_MPV_encode_end, | .close = ff_MPV_encode_end, | ||||
| .supported_framerates= avpriv_frame_rate_tab+1, | .supported_framerates= avpriv_frame_rate_tab+1, | ||||
| .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, | .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, | ||||
| @@ -969,7 +969,7 @@ AVCodec ff_mpeg2video_encoder = { | |||||
| .id = CODEC_ID_MPEG2VIDEO, | .id = CODEC_ID_MPEG2VIDEO, | ||||
| .priv_data_size = sizeof(MpegEncContext), | .priv_data_size = sizeof(MpegEncContext), | ||||
| .init = encode_init, | .init = encode_init, | ||||
| .encode = ff_MPV_encode_picture, | |||||
| .encode2 = ff_MPV_encode_picture, | |||||
| .close = ff_MPV_encode_end, | .close = ff_MPV_encode_end, | ||||
| .supported_framerates= avpriv_frame_rate_tab+1, | .supported_framerates= avpriv_frame_rate_tab+1, | ||||
| .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_YUV422P, PIX_FMT_NONE}, | .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_YUV422P, PIX_FMT_NONE}, | ||||
| @@ -1336,7 +1336,7 @@ AVCodec ff_mpeg4_encoder = { | |||||
| .id = CODEC_ID_MPEG4, | .id = CODEC_ID_MPEG4, | ||||
| .priv_data_size = sizeof(MpegEncContext), | .priv_data_size = sizeof(MpegEncContext), | ||||
| .init = encode_init, | .init = encode_init, | ||||
| .encode = ff_MPV_encode_picture, | |||||
| .encode2 = ff_MPV_encode_picture, | |||||
| .close = ff_MPV_encode_end, | .close = ff_MPV_encode_end, | ||||
| .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, | .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, | ||||
| .capabilities= CODEC_CAP_DELAY | CODEC_CAP_SLICE_THREADS, | .capabilities= CODEC_CAP_DELAY | CODEC_CAP_SLICE_THREADS, | ||||
| @@ -261,6 +261,14 @@ typedef struct MpegEncContext { | |||||
| * offsets used in asm. */ | * offsets used in asm. */ | ||||
| int64_t user_specified_pts;///< last non zero pts from AVFrame which was passed into avcodec_encode_video() | int64_t user_specified_pts;///< last non zero pts from AVFrame which was passed into avcodec_encode_video() | ||||
| /** | |||||
| * pts difference between the first and second input frame, used for | |||||
| * calculating dts of the first frame when there's a delay */ | |||||
| int64_t dts_delta; | |||||
| /** | |||||
| * reordered pts to be used as dts for the next output frame when there's | |||||
| * a delay */ | |||||
| int64_t reordered_pts; | |||||
| /** bit output */ | /** bit output */ | ||||
| PutBitContext pb; | PutBitContext pb; | ||||
| @@ -694,7 +702,8 @@ int ff_MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx); | |||||
| void ff_MPV_frame_end(MpegEncContext *s); | void ff_MPV_frame_end(MpegEncContext *s); | ||||
| int ff_MPV_encode_init(AVCodecContext *avctx); | int ff_MPV_encode_init(AVCodecContext *avctx); | ||||
| int ff_MPV_encode_end(AVCodecContext *avctx); | int ff_MPV_encode_end(AVCodecContext *avctx); | ||||
| int ff_MPV_encode_picture(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data); | |||||
| int ff_MPV_encode_picture(AVCodecContext *avctx, AVPacket *pkt, | |||||
| const AVFrame *frame, int *got_packet); | |||||
| void ff_MPV_common_init_mmx(MpegEncContext *s); | void ff_MPV_common_init_mmx(MpegEncContext *s); | ||||
| void ff_MPV_common_init_axp(MpegEncContext *s); | void ff_MPV_common_init_axp(MpegEncContext *s); | ||||
| void ff_MPV_common_init_mmi(MpegEncContext *s); | void ff_MPV_common_init_mmi(MpegEncContext *s); | ||||
| @@ -909,6 +909,9 @@ static int load_input_picture(MpegEncContext *s, AVFrame *pic_arg) | |||||
| "last=%"PRId64"\n", pts, s->user_specified_pts); | "last=%"PRId64"\n", pts, s->user_specified_pts); | ||||
| return -1; | return -1; | ||||
| } | } | ||||
| if (!s->low_delay && pic_arg->display_picture_number == 1) | |||||
| s->dts_delta = time - last; | |||||
| } | } | ||||
| s->user_specified_pts = pts; | s->user_specified_pts = pts; | ||||
| } else { | } else { | ||||
| @@ -1374,20 +1377,23 @@ no_output_pic: | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| int ff_MPV_encode_picture(AVCodecContext *avctx, | |||||
| unsigned char *buf, int buf_size, void *data) | |||||
| int ff_MPV_encode_picture(AVCodecContext *avctx, AVPacket *pkt, | |||||
| const AVFrame *pic_arg, int *got_packet) | |||||
| { | { | ||||
| MpegEncContext *s = avctx->priv_data; | MpegEncContext *s = avctx->priv_data; | ||||
| AVFrame *pic_arg = data; | |||||
| int i, stuffing_count; | |||||
| int i, stuffing_count, ret; | |||||
| int context_count = s->slice_context_count; | int context_count = s->slice_context_count; | ||||
| if (!pkt->data && | |||||
| (ret = ff_alloc_packet(pkt, s->mb_width*s->mb_height*MAX_MB_BYTES)) < 0) | |||||
| return ret; | |||||
| for (i = 0; i < context_count; i++) { | for (i = 0; i < context_count; i++) { | ||||
| int start_y = s->thread_context[i]->start_mb_y; | int start_y = s->thread_context[i]->start_mb_y; | ||||
| int end_y = s->thread_context[i]-> end_mb_y; | int end_y = s->thread_context[i]-> end_mb_y; | ||||
| int h = s->mb_height; | int h = s->mb_height; | ||||
| uint8_t *start = buf + (size_t)(((int64_t) buf_size) * start_y / h); | |||||
| uint8_t *end = buf + (size_t)(((int64_t) buf_size) * end_y / h); | |||||
| uint8_t *start = pkt->data + (size_t)(((int64_t) pkt->size) * start_y / h); | |||||
| uint8_t *end = pkt->data + (size_t)(((int64_t) pkt->size) * end_y / h); | |||||
| init_put_bits(&s->thread_context[i]->pb, start, end - start); | init_put_bits(&s->thread_context[i]->pb, start, end - start); | ||||
| } | } | ||||
| @@ -1547,13 +1553,27 @@ vbv_retry: | |||||
| } | } | ||||
| s->total_bits += s->frame_bits; | s->total_bits += s->frame_bits; | ||||
| avctx->frame_bits = s->frame_bits; | avctx->frame_bits = s->frame_bits; | ||||
| pkt->pts = s->current_picture.f.pts; | |||||
| if (!s->low_delay) { | |||||
| if (!s->current_picture.f.coded_picture_number) | |||||
| pkt->dts = pkt->pts - s->dts_delta; | |||||
| else | |||||
| pkt->dts = s->reordered_pts; | |||||
| s->reordered_pts = s->input_picture[0]->f.pts; | |||||
| } else | |||||
| pkt->dts = pkt->pts; | |||||
| if (s->current_picture.f.key_frame) | |||||
| pkt->flags |= AV_PKT_FLAG_KEY; | |||||
| } else { | } else { | ||||
| assert((put_bits_ptr(&s->pb) == s->pb.buf)); | assert((put_bits_ptr(&s->pb) == s->pb.buf)); | ||||
| s->frame_bits = 0; | s->frame_bits = 0; | ||||
| } | } | ||||
| assert((s->frame_bits & 7) == 0); | assert((s->frame_bits & 7) == 0); | ||||
| return s->frame_bits / 8; | |||||
| pkt->size = s->frame_bits / 8; | |||||
| *got_packet = !!pkt->size; | |||||
| return 0; | |||||
| } | } | ||||
| static inline void dct_single_coeff_elimination(MpegEncContext *s, | static inline void dct_single_coeff_elimination(MpegEncContext *s, | ||||
| @@ -4042,7 +4062,7 @@ AVCodec ff_h263_encoder = { | |||||
| .id = CODEC_ID_H263, | .id = CODEC_ID_H263, | ||||
| .priv_data_size = sizeof(MpegEncContext), | .priv_data_size = sizeof(MpegEncContext), | ||||
| .init = ff_MPV_encode_init, | .init = ff_MPV_encode_init, | ||||
| .encode = ff_MPV_encode_picture, | |||||
| .encode2 = ff_MPV_encode_picture, | |||||
| .close = ff_MPV_encode_end, | .close = ff_MPV_encode_end, | ||||
| .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, | .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, | ||||
| .long_name= NULL_IF_CONFIG_SMALL("H.263 / H.263-1996"), | .long_name= NULL_IF_CONFIG_SMALL("H.263 / H.263-1996"), | ||||
| @@ -4069,7 +4089,7 @@ AVCodec ff_h263p_encoder = { | |||||
| .id = CODEC_ID_H263P, | .id = CODEC_ID_H263P, | ||||
| .priv_data_size = sizeof(MpegEncContext), | .priv_data_size = sizeof(MpegEncContext), | ||||
| .init = ff_MPV_encode_init, | .init = ff_MPV_encode_init, | ||||
| .encode = ff_MPV_encode_picture, | |||||
| .encode2 = ff_MPV_encode_picture, | |||||
| .close = ff_MPV_encode_end, | .close = ff_MPV_encode_end, | ||||
| .capabilities = CODEC_CAP_SLICE_THREADS, | .capabilities = CODEC_CAP_SLICE_THREADS, | ||||
| .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, | .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, | ||||
| @@ -4083,7 +4103,7 @@ AVCodec ff_msmpeg4v2_encoder = { | |||||
| .id = CODEC_ID_MSMPEG4V2, | .id = CODEC_ID_MSMPEG4V2, | ||||
| .priv_data_size = sizeof(MpegEncContext), | .priv_data_size = sizeof(MpegEncContext), | ||||
| .init = ff_MPV_encode_init, | .init = ff_MPV_encode_init, | ||||
| .encode = ff_MPV_encode_picture, | |||||
| .encode2 = ff_MPV_encode_picture, | |||||
| .close = ff_MPV_encode_end, | .close = ff_MPV_encode_end, | ||||
| .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, | .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, | ||||
| .long_name= NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Microsoft variant version 2"), | .long_name= NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Microsoft variant version 2"), | ||||
| @@ -4095,7 +4115,7 @@ AVCodec ff_msmpeg4v3_encoder = { | |||||
| .id = CODEC_ID_MSMPEG4V3, | .id = CODEC_ID_MSMPEG4V3, | ||||
| .priv_data_size = sizeof(MpegEncContext), | .priv_data_size = sizeof(MpegEncContext), | ||||
| .init = ff_MPV_encode_init, | .init = ff_MPV_encode_init, | ||||
| .encode = ff_MPV_encode_picture, | |||||
| .encode2 = ff_MPV_encode_picture, | |||||
| .close = ff_MPV_encode_end, | .close = ff_MPV_encode_end, | ||||
| .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, | .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, | ||||
| .long_name= NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Microsoft variant version 3"), | .long_name= NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Microsoft variant version 3"), | ||||
| @@ -4107,7 +4127,7 @@ AVCodec ff_wmv1_encoder = { | |||||
| .id = CODEC_ID_WMV1, | .id = CODEC_ID_WMV1, | ||||
| .priv_data_size = sizeof(MpegEncContext), | .priv_data_size = sizeof(MpegEncContext), | ||||
| .init = ff_MPV_encode_init, | .init = ff_MPV_encode_init, | ||||
| .encode = ff_MPV_encode_picture, | |||||
| .encode2 = ff_MPV_encode_picture, | |||||
| .close = ff_MPV_encode_end, | .close = ff_MPV_encode_end, | ||||
| .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, | .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, | ||||
| .long_name= NULL_IF_CONFIG_SMALL("Windows Media Video 7"), | .long_name= NULL_IF_CONFIG_SMALL("Windows Media Video 7"), | ||||
| @@ -62,7 +62,7 @@ AVCodec ff_rv10_encoder = { | |||||
| .id = CODEC_ID_RV10, | .id = CODEC_ID_RV10, | ||||
| .priv_data_size = sizeof(MpegEncContext), | .priv_data_size = sizeof(MpegEncContext), | ||||
| .init = ff_MPV_encode_init, | .init = ff_MPV_encode_init, | ||||
| .encode = ff_MPV_encode_picture, | |||||
| .encode2 = ff_MPV_encode_picture, | |||||
| .close = ff_MPV_encode_end, | .close = ff_MPV_encode_end, | ||||
| .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, | .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, | ||||
| .long_name= NULL_IF_CONFIG_SMALL("RealVideo 1.0"), | .long_name= NULL_IF_CONFIG_SMALL("RealVideo 1.0"), | ||||
| @@ -63,7 +63,7 @@ AVCodec ff_rv20_encoder = { | |||||
| .id = CODEC_ID_RV20, | .id = CODEC_ID_RV20, | ||||
| .priv_data_size = sizeof(MpegEncContext), | .priv_data_size = sizeof(MpegEncContext), | ||||
| .init = ff_MPV_encode_init, | .init = ff_MPV_encode_init, | ||||
| .encode = ff_MPV_encode_picture, | |||||
| .encode2 = ff_MPV_encode_picture, | |||||
| .close = ff_MPV_encode_end, | .close = ff_MPV_encode_end, | ||||
| .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, | .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, | ||||
| .long_name= NULL_IF_CONFIG_SMALL("RealVideo 2.0"), | .long_name= NULL_IF_CONFIG_SMALL("RealVideo 2.0"), | ||||
| @@ -217,7 +217,7 @@ AVCodec ff_wmv2_encoder = { | |||||
| .id = CODEC_ID_WMV2, | .id = CODEC_ID_WMV2, | ||||
| .priv_data_size = sizeof(Wmv2Context), | .priv_data_size = sizeof(Wmv2Context), | ||||
| .init = wmv2_encode_init, | .init = wmv2_encode_init, | ||||
| .encode = ff_MPV_encode_picture, | |||||
| .encode2 = ff_MPV_encode_picture, | |||||
| .close = ff_MPV_encode_end, | .close = ff_MPV_encode_end, | ||||
| .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, | .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, | ||||
| .long_name= NULL_IF_CONFIG_SMALL("Windows Media Video 8"), | .long_name= NULL_IF_CONFIG_SMALL("Windows Media Video 8"), | ||||