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); | ||||
} | } | ||||