X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fmpeg12enc.c;h=3376f1075f4b7582a8e4556e98deddab3e049dab;hb=c442190a6bfd8036f6c32b78e1e96ff3b830f8f0;hp=2010d2af8e4a5fac9cb725ef61538fd42e404bcb;hpb=7f93a861aaf2e76fd63b53ccc465909873b8dc29;p=ffmpeg diff --git a/libavcodec/mpeg12enc.c b/libavcodec/mpeg12enc.c index 2010d2af8e4..3376f1075f4 100644 --- a/libavcodec/mpeg12enc.c +++ b/libavcodec/mpeg12enc.c @@ -25,14 +25,19 @@ * MPEG1/2 encoder */ +#include + #include "libavutil/attributes.h" #include "libavutil/log.h" #include "libavutil/opt.h" +#include "libavutil/stereo3d.h" + #include "avcodec.h" #include "bytestream.h" #include "mathops.h" #include "mpeg12.h" #include "mpeg12data.h" +#include "mpegutils.h" #include "mpegvideo.h" @@ -126,7 +131,7 @@ static av_cold int encode_init(AVCodecContext *avctx) { MpegEncContext *s = avctx->priv_data; - if (ff_MPV_encode_init(avctx) < 0) + if (ff_mpv_encode_init(avctx) < 0) return -1; if (find_frame_rate_index(s) < 0) { @@ -199,7 +204,7 @@ static void mpeg1_encode_sequence_header(MpegEncContext *s) if (aspect_ratio == 0.0) aspect_ratio = 1.0; // pixel aspect 1.1 (VGA) - if (s->current_picture.f.key_frame) { + if (s->current_picture.f->key_frame) { AVRational framerate = ff_mpeg12_frame_rate_tab[s->frame_rate_index]; /* mpeg1 header repeated every gop */ @@ -282,6 +287,18 @@ static void mpeg1_encode_sequence_header(MpegEncContext *s) put_bits(&s->pb, 1, s->low_delay); put_bits(&s->pb, 2, 0); // frame_rate_ext_n put_bits(&s->pb, 5, 0); // frame_rate_ext_d + + put_header(s, EXT_START_CODE); + put_bits(&s->pb, 4, 2); // sequence display extension + put_bits(&s->pb, 3, 0); // video_format: 0 is components + put_bits(&s->pb, 1, 1); // colour_description + put_bits(&s->pb, 8, s->avctx->color_primaries); // colour_primaries + put_bits(&s->pb, 8, s->avctx->color_trc); // transfer_characteristics + put_bits(&s->pb, 8, s->avctx->colorspace); // matrix_coefficients + put_bits(&s->pb, 14, s->width); // display_horizontal_size + put_bits(&s->pb, 1, 1); // marker_bit + put_bits(&s->pb, 14, s->height); // display_vertical_size + put_bits(&s->pb, 3, 0); // remaining 3 bits are zero padding } put_header(s, GOP_START_CODE); @@ -289,10 +306,10 @@ static void mpeg1_encode_sequence_header(MpegEncContext *s) /* time code: we must convert from the real frame rate to a * fake MPEG frame rate in case of low frame rate */ fps = (framerate.num + framerate.den / 2) / framerate.den; - time_code = s->current_picture_ptr->f.coded_picture_number + + time_code = s->current_picture_ptr->f->coded_picture_number + s->avctx->timecode_frame_start; - s->gop_picture_number = s->current_picture_ptr->f.coded_picture_number; + s->gop_picture_number = s->current_picture_ptr->f->coded_picture_number; if (s->drop_frame_timecode) { /* only works for NTSC 29.97 */ int d = time_code / 17982; @@ -348,6 +365,7 @@ void ff_mpeg1_encode_slice_header(MpegEncContext *s) void ff_mpeg1_encode_picture_header(MpegEncContext *s, int picture_number) { + AVFrameSideData *side_data; mpeg1_encode_sequence_header(s); /* mpeg1 picture header */ @@ -407,7 +425,7 @@ void ff_mpeg1_encode_picture_header(MpegEncContext *s, int picture_number) if (s->progressive_sequence) put_bits(&s->pb, 1, 0); /* no repeat */ else - put_bits(&s->pb, 1, s->current_picture_ptr->f.top_field_first); + put_bits(&s->pb, 1, s->current_picture_ptr->f->top_field_first); /* XXX: optimize the generation of this flag with entropy measures */ s->frame_pred_frame_dct = s->progressive_sequence; @@ -431,6 +449,44 @@ void ff_mpeg1_encode_picture_header(MpegEncContext *s, int picture_number) for (i = 0; i < sizeof(svcd_scan_offset_placeholder); i++) put_bits(&s->pb, 8, svcd_scan_offset_placeholder[i]); } + side_data = av_frame_get_side_data(s->current_picture_ptr->f, + AV_FRAME_DATA_STEREO3D); + if (side_data) { + AVStereo3D *stereo = (AVStereo3D *)side_data->data; + uint8_t fpa_type; + + switch (stereo->type) { + case AV_STEREO3D_SIDEBYSIDE: + fpa_type = 0x03; + break; + case AV_STEREO3D_TOPBOTTOM: + fpa_type = 0x04; + break; + case AV_STEREO3D_2D: + fpa_type = 0x08; + break; + case AV_STEREO3D_SIDEBYSIDE_QUINCUNX: + fpa_type = 0x23; + break; + default: + fpa_type = 0; + break; + } + + if (fpa_type != 0) { + put_header(s, USER_START_CODE); + put_bits(&s->pb, 8, 'J'); // S3D_video_format_signaling_identifier + put_bits(&s->pb, 8, 'P'); + put_bits(&s->pb, 8, '3'); + put_bits(&s->pb, 8, 'D'); + put_bits(&s->pb, 8, 0x03); // S3D_video_format_length + + put_bits(&s->pb, 1, 1); // reserved_bit + put_bits(&s->pb, 7, fpa_type); // S3D_video_format_type + put_bits(&s->pb, 8, 0x04); // reserved_data[0] + put_bits(&s->pb, 8, 0xFF); // reserved_data[1] + } + } s->mb_y = 0; ff_mpeg1_encode_slice_header(s); @@ -1022,33 +1078,33 @@ mpeg12_class(2) AVCodec ff_mpeg1video_encoder = { .name = "mpeg1video", + .long_name = NULL_IF_CONFIG_SMALL("MPEG-1 video"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_MPEG1VIDEO, .priv_data_size = sizeof(MpegEncContext), .init = encode_init, - .encode2 = ff_MPV_encode_picture, - .close = ff_MPV_encode_end, + .encode2 = ff_mpv_encode_picture, + .close = ff_mpv_encode_end, .supported_framerates = ff_mpeg12_frame_rate_tab + 1, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE }, .capabilities = CODEC_CAP_DELAY | CODEC_CAP_SLICE_THREADS, - .long_name = NULL_IF_CONFIG_SMALL("MPEG-1 video"), .priv_class = &mpeg1_class, }; AVCodec ff_mpeg2video_encoder = { .name = "mpeg2video", + .long_name = NULL_IF_CONFIG_SMALL("MPEG-2 video"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_MPEG2VIDEO, .priv_data_size = sizeof(MpegEncContext), .init = encode_init, - .encode2 = ff_MPV_encode_picture, - .close = ff_MPV_encode_end, + .encode2 = ff_mpv_encode_picture, + .close = ff_mpv_encode_end, .supported_framerates = ff_mpeg12_frame_rate_tab + 1, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_NONE }, .capabilities = CODEC_CAP_DELAY | CODEC_CAP_SLICE_THREADS, - .long_name = NULL_IF_CONFIG_SMALL("MPEG-2 video"), .priv_class = &mpeg2_class, };