Signed-off-by: Michael Niedermayer <michaelni@gmx.at>tags/n1.0
| @@ -196,7 +196,8 @@ static int encode_picture_lossless(AVCodecContext *avctx, AVPacket *pkt, | |||||
| } | } | ||||
| emms_c(); | emms_c(); | ||||
| av_assert0(s->esc_pos == s->header_bits >> 3); | |||||
| ff_mjpeg_encode_stuffing(s); | |||||
| ff_mjpeg_encode_picture_trailer(s); | ff_mjpeg_encode_picture_trailer(s); | ||||
| s->picture_number++; | s->picture_number++; | ||||
| @@ -137,6 +137,12 @@ static void jpeg_table_header(MpegEncContext *s) | |||||
| } | } | ||||
| #endif | #endif | ||||
| if(s->avctx->active_thread_type & FF_THREAD_SLICE){ | |||||
| put_marker(p, DRI); | |||||
| put_bits(p, 16, 4); | |||||
| put_bits(p, 16, s->mb_width); | |||||
| } | |||||
| /* huffman table */ | /* huffman table */ | ||||
| put_marker(p, DHT); | put_marker(p, DHT); | ||||
| flush_put_bits(p); | flush_put_bits(p); | ||||
| @@ -202,11 +208,12 @@ static void jpeg_put_comments(MpegEncContext *s) | |||||
| void ff_mjpeg_encode_picture_header(MpegEncContext *s) | void ff_mjpeg_encode_picture_header(MpegEncContext *s) | ||||
| { | { | ||||
| const int lossless= s->avctx->codec_id != CODEC_ID_MJPEG; | const int lossless= s->avctx->codec_id != CODEC_ID_MJPEG; | ||||
| int i; | |||||
| put_marker(&s->pb, SOI); | put_marker(&s->pb, SOI); | ||||
| // hack for AMV mjpeg format | // hack for AMV mjpeg format | ||||
| if(s->avctx->codec_id == CODEC_ID_AMV) return; | |||||
| if(s->avctx->codec_id == CODEC_ID_AMV) goto end; | |||||
| jpeg_put_comments(s); | jpeg_put_comments(s); | ||||
| @@ -284,6 +291,11 @@ void ff_mjpeg_encode_picture_header(MpegEncContext *s) | |||||
| } | } | ||||
| put_bits(&s->pb, 8, 0); /* Ah/Al (not used) */ | put_bits(&s->pb, 8, 0); /* Ah/Al (not used) */ | ||||
| end: | |||||
| s->esc_pos = put_bits_count(&s->pb) >> 3; | |||||
| for(i=1; i<s->slice_context_count; i++) | |||||
| s->thread_context[i]->esc_pos = 0; | |||||
| } | } | ||||
| static void escape_FF(MpegEncContext *s, int start) | static void escape_FF(MpegEncContext *s, int start) | ||||
| @@ -339,21 +351,30 @@ static void escape_FF(MpegEncContext *s, int start) | |||||
| } | } | ||||
| } | } | ||||
| void ff_mjpeg_encode_stuffing(PutBitContext * pbc) | |||||
| void ff_mjpeg_encode_stuffing(MpegEncContext *s) | |||||
| { | { | ||||
| int length; | |||||
| int length, i; | |||||
| PutBitContext *pbc = &s->pb; | |||||
| int mb_y = s->mb_y - !s->mb_x; | |||||
| length= (-put_bits_count(pbc))&7; | length= (-put_bits_count(pbc))&7; | ||||
| if(length) put_bits(pbc, length, (1<<length)-1); | if(length) put_bits(pbc, length, (1<<length)-1); | ||||
| flush_put_bits(&s->pb); | |||||
| escape_FF(s, s->esc_pos); | |||||
| if((s->avctx->active_thread_type & FF_THREAD_SLICE) && mb_y < s->mb_height) | |||||
| put_marker(pbc, RST0 + (mb_y&7)); | |||||
| s->esc_pos = put_bits_count(pbc) >> 3; | |||||
| for(i=0; i<3; i++) | |||||
| s->last_dc[i] = 128 << s->intra_dc_precision; | |||||
| } | } | ||||
| void ff_mjpeg_encode_picture_trailer(MpegEncContext *s) | void ff_mjpeg_encode_picture_trailer(MpegEncContext *s) | ||||
| { | { | ||||
| ff_mjpeg_encode_stuffing(&s->pb); | |||||
| flush_put_bits(&s->pb); | |||||
| assert((s->header_bits&7)==0); | assert((s->header_bits&7)==0); | ||||
| escape_FF(s, s->header_bits>>3); | |||||
| put_marker(&s->pb, EOI); | put_marker(&s->pb, EOI); | ||||
| } | } | ||||
| @@ -485,6 +506,7 @@ AVCodec ff_mjpeg_encoder = { | |||||
| .init = ff_MPV_encode_init, | .init = ff_MPV_encode_init, | ||||
| .encode2 = ff_MPV_encode_picture, | .encode2 = ff_MPV_encode_picture, | ||||
| .close = ff_MPV_encode_end, | .close = ff_MPV_encode_end, | ||||
| .capabilities = CODEC_CAP_SLICE_THREADS, | |||||
| .pix_fmts = (const enum PixelFormat[]){ | .pix_fmts = (const enum PixelFormat[]){ | ||||
| PIX_FMT_YUVJ420P, PIX_FMT_YUVJ422P, PIX_FMT_NONE | PIX_FMT_YUVJ420P, PIX_FMT_YUVJ422P, PIX_FMT_NONE | ||||
| }, | }, | ||||
| @@ -52,7 +52,7 @@ int ff_mjpeg_encode_init(MpegEncContext *s); | |||||
| void ff_mjpeg_encode_close(MpegEncContext *s); | void ff_mjpeg_encode_close(MpegEncContext *s); | ||||
| void ff_mjpeg_encode_picture_header(MpegEncContext *s); | void ff_mjpeg_encode_picture_header(MpegEncContext *s); | ||||
| void ff_mjpeg_encode_picture_trailer(MpegEncContext *s); | void ff_mjpeg_encode_picture_trailer(MpegEncContext *s); | ||||
| void ff_mjpeg_encode_stuffing(PutBitContext *pbc); | |||||
| void ff_mjpeg_encode_stuffing(MpegEncContext *s); | |||||
| void ff_mjpeg_encode_dc(MpegEncContext *s, int val, | void ff_mjpeg_encode_dc(MpegEncContext *s, int val, | ||||
| uint8_t *huff_size, uint16_t *huff_code); | uint8_t *huff_size, uint16_t *huff_code); | ||||
| void ff_mjpeg_encode_mb(MpegEncContext *s, DCTELEM block[6][64]); | void ff_mjpeg_encode_mb(MpegEncContext *s, DCTELEM block[6][64]); | ||||
| @@ -599,6 +599,7 @@ typedef struct MpegEncContext { | |||||
| struct MJpegContext *mjpeg_ctx; | struct MJpegContext *mjpeg_ctx; | ||||
| int mjpeg_vsample[3]; ///< vertical sampling factors, default = {2, 1, 1} | int mjpeg_vsample[3]; ///< vertical sampling factors, default = {2, 1, 1} | ||||
| int mjpeg_hsample[3]; ///< horizontal sampling factors, default = {2, 1, 1} | int mjpeg_hsample[3]; ///< horizontal sampling factors, default = {2, 1, 1} | ||||
| int esc_pos; | |||||
| /* MSMPEG4 specific */ | /* MSMPEG4 specific */ | ||||
| int mv_table_index; | int mv_table_index; | ||||
| @@ -578,6 +578,7 @@ av_cold int ff_MPV_encode_init(AVCodecContext *avctx) | |||||
| s->codec_id != CODEC_ID_MPEG4 && | s->codec_id != CODEC_ID_MPEG4 && | ||||
| s->codec_id != CODEC_ID_MPEG1VIDEO && | s->codec_id != CODEC_ID_MPEG1VIDEO && | ||||
| s->codec_id != CODEC_ID_MPEG2VIDEO && | s->codec_id != CODEC_ID_MPEG2VIDEO && | ||||
| s->codec_id != CODEC_ID_MJPEG && | |||||
| (s->codec_id != CODEC_ID_H263P)) { | (s->codec_id != CODEC_ID_H263P)) { | ||||
| av_log(avctx, AV_LOG_ERROR, | av_log(avctx, AV_LOG_ERROR, | ||||
| "multi threaded encoding not supported by codec\n"); | "multi threaded encoding not supported by codec\n"); | ||||
| @@ -2372,7 +2373,7 @@ static void write_slice_end(MpegEncContext *s){ | |||||
| ff_mpeg4_stuffing(&s->pb); | ff_mpeg4_stuffing(&s->pb); | ||||
| }else if(CONFIG_MJPEG_ENCODER && s->out_format == FMT_MJPEG){ | }else if(CONFIG_MJPEG_ENCODER && s->out_format == FMT_MJPEG){ | ||||
| ff_mjpeg_encode_stuffing(&s->pb); | |||||
| ff_mjpeg_encode_stuffing(s); | |||||
| } | } | ||||
| avpriv_align_put_bits(&s->pb); | avpriv_align_put_bits(&s->pb); | ||||
| @@ -2547,12 +2548,14 @@ static int encode_thread(AVCodecContext *c, void *arg){ | |||||
| case CODEC_ID_MPEG1VIDEO: | case CODEC_ID_MPEG1VIDEO: | ||||
| if(s->mb_skip_run) is_gob_start=0; | if(s->mb_skip_run) is_gob_start=0; | ||||
| break; | break; | ||||
| case CODEC_ID_MJPEG: | |||||
| if(s->mb_x==0 && s->mb_y!=0) is_gob_start=1; | |||||
| break; | |||||
| } | } | ||||
| if(is_gob_start){ | if(is_gob_start){ | ||||
| if(s->start_mb_y != mb_y || mb_x!=0){ | if(s->start_mb_y != mb_y || mb_x!=0){ | ||||
| write_slice_end(s); | write_slice_end(s); | ||||
| if(CONFIG_MPEG4_ENCODER && s->codec_id==CODEC_ID_MPEG4 && s->partitioned_frame){ | if(CONFIG_MPEG4_ENCODER && s->codec_id==CODEC_ID_MPEG4 && s->partitioned_frame){ | ||||
| ff_mpeg4_init_partitions(s); | ff_mpeg4_init_partitions(s); | ||||
| } | } | ||||