@ -118,85 +118,43 @@ static int ljpeg_encode_bgr(AVCodecContext *avctx, PutBitContext *pb,
return 0 ;
}
static int ljpeg_encode_frame ( AVCodecContext * avctx , AVPacket * pkt ,
const AVFrame * pict , int * got_packet )
static inline void ljpeg_encode_yuv_mb ( LJpegEncContext * s , PutBitContext * pb ,
const AVFrame * frame , int predictor ,
int mb_x , int mb_y )
{
LJpegEncContext * s = avctx - > priv_data ;
PutBitContext pb ;
const int width = avctx - > width ;
const int height = avctx - > height ;
const int predictor = avctx - > prediction_method + 1 ;
const int mb_width = ( width + s - > hsample [ 0 ] - 1 ) / s - > hsample [ 0 ] ;
const int mb_height = ( height + s - > vsample [ 0 ] - 1 ) / s - > vsample [ 0 ] ;
int max_pkt_size = FF_MIN_BUFFER_SIZE ;
int ret , header_bits ;
if ( avctx - > pix_fmt = = AV_PIX_FMT_BGR0
| | avctx - > pix_fmt = = AV_PIX_FMT_BGRA
| | avctx - > pix_fmt = = AV_PIX_FMT_BGR24 )
max_pkt_size + = width * height * 3 * 4 ;
else {
max_pkt_size + = mb_width * mb_height * 3 * 4
* s - > hsample [ 0 ] * s - > vsample [ 0 ] ;
}
int i ;
if ( ( ret = ff_alloc_packet2 ( avctx , pkt , max_pkt_size ) ) < 0 )
return ret ;
init_put_bits ( & pb , pkt - > data , pkt - > size ) ;
ff_mjpeg_encode_picture_header ( avctx , & pb , & s - > scantable ,
s - > matrix ) ;
header_bits = put_bits_count ( & pb ) ;
if ( avctx - > pix_fmt = = AV_PIX_FMT_BGR0
| | avctx - > pix_fmt = = AV_PIX_FMT_BGRA
| | avctx - > pix_fmt = = AV_PIX_FMT_BGR24 ) {
ret = ljpeg_encode_bgr ( avctx , & pb , pict ) ;
if ( ret < 0 )
return ret ;
} else {
int mb_x , mb_y , i ;
for ( mb_y = 0 ; mb_y < mb_height ; mb_y + + ) {
if ( pb . buf_end - pb . buf - ( put_bits_count ( & pb ) > > 3 ) <
mb_width * 4 * 3 * s - > hsample [ 0 ] * s - > vsample [ 0 ] ) {
av_log ( avctx , AV_LOG_ERROR , " encoded frame too large \n " ) ;
return - 1 ;
}
for ( mb_x = 0 ; mb_x < mb_width ; mb_x + + ) {
if ( mb_x = = 0 | | mb_y = = 0 ) {
for ( i = 0 ; i < 3 ; i + + ) {
uint8_t * ptr ;
int x , y , h , v , linesize ;
h = s - > hsample [ i ] ;
v = s - > vsample [ i ] ;
linesize = pict - > linesize [ i ] ;
linesize = frame - > linesize [ i ] ;
for ( y = 0 ; y < v ; y + + ) {
for ( x = 0 ; x < h ; x + + ) {
int pred ;
ptr = pict - > data [ i ] + ( linesize * ( v * mb_y + y ) ) + ( h * mb_x + x ) ; //FIXME optimize this crap
ptr = frame - > data [ i ] + ( linesize * ( v * mb_y + y ) ) + ( h * mb_x + x ) ; //FIXME optimize this crap
if ( y = = 0 & & mb_y = = 0 ) {
if ( x = = 0 & & mb_x = = 0 ) {
if ( x = = 0 & & mb_x = = 0 )
pred = 128 ;
} else {
else
pred = ptr [ - 1 ] ;
}
} else {
if ( x = = 0 & & mb_x = = 0 ) {
pred = ptr [ - linesize ] ;
} else {
PREDICT ( pred , ptr [ - linesize - 1 ] , ptr [ - linesize ] , ptr [ - 1 ] , predictor ) ;
PREDICT ( pred , ptr [ - linesize - 1 ] , ptr [ - linesize ] ,
ptr [ - 1 ] , predictor ) ;
}
}
if ( i = = 0 )
ff_mjpeg_encode_dc ( & pb , * ptr - pred , s - > huff_size_dc_luminance , s - > huff_code_dc_luminance ) ; //FIXME ugly
ff_mjpeg_encode_dc ( pb , * ptr - pred , s - > huff_size_dc_luminance , s - > huff_code_dc_luminance ) ; //FIXME ugly
else
ff_mjpeg_encode_dc ( & pb , * ptr - pred , s - > huff_size_dc_chrominance , s - > huff_code_dc_chrominance ) ;
ff_mjpeg_encode_dc ( pb , * ptr - pred , s - > huff_size_dc_chrominance , s - > huff_code_dc_chrominance ) ;
}
}
}
@ -206,27 +164,88 @@ static int ljpeg_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
int x , y , h , v , linesize ;
h = s - > hsample [ i ] ;
v = s - > vsample [ i ] ;
linesize = pict - > linesize [ i ] ;
linesize = frame - > linesize [ i ] ;
for ( y = 0 ; y < v ; y + + ) {
for ( x = 0 ; x < h ; x + + ) {
int pred ;
ptr = pict - > data [ i ] + ( linesize * ( v * mb_y + y ) ) + ( h * mb_x + x ) ; //FIXME optimize this crap
ptr = frame - > data [ i ] + ( linesize * ( v * mb_y + y ) ) + ( h * mb_x + x ) ; //FIXME optimize this crap
PREDICT ( pred , ptr [ - linesize - 1 ] , ptr [ - linesize ] , ptr [ - 1 ] , predictor ) ;
if ( i = = 0 )
ff_mjpeg_encode_dc ( & pb , * ptr - pred , s - > huff_size_dc_luminance , s - > huff_code_dc_luminance ) ; //FIXME ugly
ff_mjpeg_encode_dc ( pb , * ptr - pred , s - > huff_size_dc_luminance , s - > huff_code_dc_luminance ) ; //FIXME ugly
else
ff_mjpeg_encode_dc ( & pb , * ptr - pred , s - > huff_size_dc_chrominance , s - > huff_code_dc_chrominance ) ;
ff_mjpeg_encode_dc ( pb , * ptr - pred , s - > huff_size_dc_chrominance , s - > huff_code_dc_chrominance ) ;
}
}
}
}
}
static int ljpeg_encode_yuv ( AVCodecContext * avctx , PutBitContext * pb ,
const AVFrame * frame )
{
const int predictor = avctx - > prediction_method + 1 ;
LJpegEncContext * s = avctx - > priv_data ;
const int mb_width = ( avctx - > width + s - > hsample [ 0 ] - 1 ) / s - > hsample [ 0 ] ;
const int mb_height = ( avctx - > height + s - > vsample [ 0 ] - 1 ) / s - > vsample [ 0 ] ;
int mb_x , mb_y ;
for ( mb_y = 0 ; mb_y < mb_height ; mb_y + + ) {
if ( pb - > buf_end - pb - > buf - ( put_bits_count ( pb ) > > 3 ) <
mb_width * 4 * 3 * s - > hsample [ 0 ] * s - > vsample [ 0 ] ) {
av_log ( avctx , AV_LOG_ERROR , " encoded frame too large \n " ) ;
return - 1 ;
}
for ( mb_x = 0 ; mb_x < mb_width ; mb_x + + )
ljpeg_encode_yuv_mb ( s , pb , frame , predictor , mb_x , mb_y ) ;
}
return 0 ;
}
static int ljpeg_encode_frame ( AVCodecContext * avctx , AVPacket * pkt ,
const AVFrame * pict , int * got_packet )
{
LJpegEncContext * s = avctx - > priv_data ;
PutBitContext pb ;
const int width = avctx - > width ;
const int height = avctx - > height ;
const int mb_width = ( width + s - > hsample [ 0 ] - 1 ) / s - > hsample [ 0 ] ;
const int mb_height = ( height + s - > vsample [ 0 ] - 1 ) / s - > vsample [ 0 ] ;
int max_pkt_size = FF_MIN_BUFFER_SIZE ;
int ret , header_bits ;
if ( avctx - > pix_fmt = = AV_PIX_FMT_BGR0
| | avctx - > pix_fmt = = AV_PIX_FMT_BGRA
| | avctx - > pix_fmt = = AV_PIX_FMT_BGR24 )
max_pkt_size + = width * height * 3 * 4 ;
else {
max_pkt_size + = mb_width * mb_height * 3 * 4
* s - > hsample [ 0 ] * s - > vsample [ 0 ] ;
}
if ( ( ret = ff_alloc_packet2 ( avctx , pkt , max_pkt_size ) ) < 0 )
return ret ;
init_put_bits ( & pb , pkt - > data , pkt - > size ) ;
ff_mjpeg_encode_picture_header ( avctx , & pb , & s - > scantable ,
s - > matrix ) ;
header_bits = put_bits_count ( & pb ) ;
if ( avctx - > pix_fmt = = AV_PIX_FMT_BGR0
| | avctx - > pix_fmt = = AV_PIX_FMT_BGRA
| | avctx - > pix_fmt = = AV_PIX_FMT_BGR24 )
ret = ljpeg_encode_bgr ( avctx , & pb , pict ) ;
else
ret = ljpeg_encode_yuv ( avctx , & pb , pict ) ;
if ( ret < 0 )
return ret ;
emms_c ( ) ;
ff_mjpeg_escape_FF ( & pb , header_bits > > 3 ) ;