826 changes: 826 additions & 0 deletions libavcodec/indeo4.c

Large diffs are not rendered by default.

350 changes: 350 additions & 0 deletions libavcodec/indeo4data.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,350 @@
/*
* Indeo Video Interactive 4 compatible decoder
* Copyright (c) 2009-2010 Maxim Poliakovski
*
* This file is part of Libav.
*
* Libav is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* Libav is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with Libav; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

/**
* @file
* This file contains data needed for the Indeo 4 decoder.
*/

#ifndef AVCODEC_INDEO4DATA_H
#define AVCODEC_INDEO4DATA_H

#include <stdint.h>
#include "dsputil.h"
#include "ivi_common.h"

/**
* standard picture dimensions
*/
static const uint16_t ivi4_common_pic_sizes[14] = {
640, 480, 320, 240, 160, 120, 704, 480, 352, 240, 352, 288, 176, 144
};

/**
* Indeo 4 8x8 scan (zigzag) patterns
*/
static const uint8_t ivi4_alternate_scan_8x8[64] = {
0, 8, 1, 9, 16, 24, 2, 3, 17, 25, 10, 11, 32, 40, 48, 56,
4, 5, 6, 7, 33, 41, 49, 57, 18, 19, 26, 27, 12, 13, 14, 15,
34, 35, 43, 42, 50, 51, 59, 58, 20, 21, 22, 23, 31, 30, 29, 28,
36, 37, 38, 39, 47, 46, 45, 44, 52, 53, 54, 55, 63, 62, 61, 60
};

static const uint8_t ivi4_alternate_scan_4x4[16] = {
0, 1, 4, 5, 8, 12, 2, 3, 9, 13, 6, 7, 10, 11, 14, 15
};

static const uint8_t ivi4_vertical_scan_4x4[16] = {
0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15
};

static const uint8_t ivi4_horizontal_scan_4x4[16] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
};

static const uint8_t *scan_index_to_tab[15] = {
// for 8x8 transforms
ff_zigzag_direct,
ivi4_alternate_scan_8x8,
ff_ivi_horizontal_scan_8x8,
ff_ivi_vertical_scan_8x8,
ff_zigzag_direct,

// for 4x4 transforms
ff_ivi_direct_scan_4x4,
ivi4_alternate_scan_4x4,
ivi4_vertical_scan_4x4,
ivi4_horizontal_scan_4x4,
ff_ivi_direct_scan_4x4,

// TODO: check if those are needed
ff_ivi_horizontal_scan_8x8,
ff_ivi_horizontal_scan_8x8,
ff_ivi_horizontal_scan_8x8,
ff_ivi_horizontal_scan_8x8,
ff_ivi_horizontal_scan_8x8
};

/**
* Indeo 4 dequant tables
*/
static uint16_t ivi4_quant_8x8_intra[9][64] = {
{
43, 342, 385, 470, 555, 555, 598, 726,
342, 342, 470, 513, 555, 598, 726, 769,
385, 470, 555, 555, 598, 726, 726, 811,
470, 470, 555, 555, 598, 726, 769, 854,
470, 555, 555, 598, 683, 726, 854, 1025,
555, 555, 598, 683, 726, 854, 1025, 1153,
555, 555, 598, 726, 811, 982, 1195, 1451,
555, 598, 726, 811, 982, 1195, 1451, 1793
},
{
86, 1195, 2390, 2390, 4865, 4865, 4865, 4865,
1195, 1195, 2390, 2390, 4865, 4865, 4865, 4865,
2390, 2390, 4865, 4865, 6827, 6827, 6827, 6827,
2390, 2390, 4865, 4865, 6827, 6827, 6827, 6827,
4865, 4865, 6827, 6827, 6827, 6827, 6827, 6827,
4865, 4865, 6827, 6827, 6827, 6827, 6827, 6827,
4865, 4865, 6827, 6827, 6827, 6827, 6827, 6827,
4865, 4865, 6827, 6827, 6827, 6827, 6827, 6827
},
{
235, 1067, 1195, 1323, 1451, 1579, 1707, 1835,
235, 1067, 1195, 1323, 1451, 1579, 1707, 1835,
235, 1067, 1195, 1323, 1451, 1579, 1707, 1835,
235, 1067, 1195, 1323, 1451, 1579, 1707, 1835,
235, 1067, 1195, 1323, 1451, 1579, 1707, 1835,
235, 1067, 1195, 1323, 1451, 1579, 1707, 1835,
235, 1067, 1195, 1323, 1451, 1579, 1707, 1835,
235, 1067, 1195, 1323, 1451, 1579, 1707, 1835
},
{
1707, 1707, 3414, 3414, 3414, 3414, 3414, 3414,
1707, 1707, 3414, 3414, 3414, 3414, 3414, 3414,
1707, 1707, 3414, 3414, 3414, 3414, 3414, 3414,
1707, 1707, 3414, 3414, 3414, 3414, 3414, 3414,
1707, 1707, 3414, 3414, 3414, 3414, 3414, 3414,
1707, 1707, 3414, 3414, 3414, 3414, 3414, 3414,
1707, 1707, 3414, 3414, 3414, 3414, 3414, 3414,
1707, 1707, 3414, 3414, 3414, 3414, 3414, 3414
},
{
897, 897, 897, 897, 897, 897, 897, 897,
1067, 1067, 1067, 1067, 1067, 1067, 1067, 1067,
1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238,
1409, 1409, 1409, 1409, 1409, 1409, 1409, 1409,
1579, 1579, 1579, 1579, 1579, 1579, 1579, 1579,
1750, 1750, 1750, 1750, 1750, 1750, 1750, 1750,
1921, 1921, 1921, 1921, 1921, 1921, 1921, 1921,
2091, 2091, 2091, 2091, 2091, 2091, 2091, 2091
},
{
1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707,
1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707,
3414, 3414, 3414, 3414, 3414, 3414, 3414, 3414,
3414, 3414, 3414, 3414, 3414, 3414, 3414, 3414,
3414, 3414, 3414, 3414, 3414, 3414, 3414, 3414,
3414, 3414, 3414, 3414, 3414, 3414, 3414, 3414,
3414, 3414, 3414, 3414, 3414, 3414, 3414, 3414,
3414, 3414, 3414, 3414, 3414, 3414, 3414, 3414
},
{
2390, 2390, 2390, 2390, 2390, 2390, 2390, 2390,
2390, 2390, 2390, 2390, 2390, 2390, 2390, 2390,
2390, 2390, 2390, 2390, 2390, 2390, 2390, 2390,
2390, 2390, 2390, 2390, 2390, 2390, 2390, 2390,
2390, 2390, 2390, 2390, 2390, 2390, 2390, 2390,
2390, 2390, 2390, 2390, 2390, 2390, 2390, 2390,
2390, 2390, 2390, 2390, 2390, 2390, 2390, 2390,
2390, 2390, 2390, 2390, 2390, 2390, 2390, 2390
},
{
22, 171, 214, 257, 257, 299, 299, 342,
171, 171, 257, 257, 299, 299, 342, 385,
214, 257, 257, 299, 299, 342, 342, 385,
257, 257, 257, 299, 299, 342, 385, 427,
257, 257, 299, 299, 342, 385, 427, 513,
257, 299, 299, 342, 385, 427, 513, 598,
299, 299, 299, 385, 385, 470, 598, 726,
299, 299, 385, 385, 470, 598, 726, 897
},
{
86, 598, 1195, 1195, 2390, 2390, 2390, 2390,
598, 598, 1195, 1195, 2390, 2390, 2390, 2390,
1195, 1195, 2390, 2390, 3414, 3414, 3414, 3414,
1195, 1195, 2390, 2390, 3414, 3414, 3414, 3414,
2390, 2390, 3414, 3414, 3414, 3414, 3414, 3414,
2390, 2390, 3414, 3414, 3414, 3414, 3414, 3414,
2390, 2390, 3414, 3414, 3414, 3414, 3414, 3414,
2390, 2390, 3414, 3414, 3414, 3414, 3414, 3414
}
};

static uint16_t ivi4_quant_8x8_inter[9][64] = {
{
427, 427, 470, 427, 427, 427, 470, 470,
427, 427, 470, 427, 427, 427, 470, 470,
470, 470, 470, 470, 470, 470, 470, 470,
427, 427, 470, 470, 427, 427, 470, 470,
427, 427, 470, 427, 427, 427, 470, 470,
427, 427, 470, 427, 427, 427, 470, 470,
470, 470, 470, 470, 470, 470, 470, 470,
470, 470, 470, 470, 470, 470, 470, 470
},
{
1707, 1707, 2433, 2433, 3414, 3414, 3414, 3414,
1707, 1707, 2433, 2433, 3414, 3414, 3414, 3414,
2433, 2433, 3414, 3414, 4822, 4822, 4822, 4822,
2433, 2433, 3414, 3414, 4822, 4822, 4822, 4822,
3414, 3414, 4822, 4822, 3414, 3414, 3414, 3414,
3414, 3414, 4822, 4822, 3414, 3414, 3414, 3414,
3414, 3414, 4822, 4822, 3414, 3414, 3414, 3414,
3414, 3414, 4822, 4822, 3414, 3414, 3414, 3414
},
{
1195, 1195, 1281, 1238, 1195, 1195, 1281, 1281,
1195, 1195, 1281, 1238, 1195, 1195, 1281, 1281,
1195, 1195, 1281, 1238, 1195, 1195, 1281, 1281,
1195, 1195, 1281, 1238, 1195, 1195, 1281, 1281,
1195, 1195, 1281, 1238, 1195, 1195, 1281, 1281,
1195, 1195, 1281, 1238, 1195, 1195, 1281, 1281,
1195, 1195, 1281, 1238, 1195, 1195, 1281, 1281,
1195, 1195, 1281, 1238, 1195, 1195, 1281, 1281
},
{
2433, 2433, 3414, 3414, 2433, 2433, 2433, 2433,
2433, 2433, 3414, 3414, 2433, 2433, 2433, 2433,
2433, 2433, 3414, 3414, 2433, 2433, 2433, 2433,
2433, 2433, 3414, 3414, 2433, 2433, 2433, 2433,
2433, 2433, 3414, 3414, 2433, 2433, 2433, 2433,
2433, 2433, 3414, 3414, 2433, 2433, 2433, 2433,
2433, 2433, 3414, 3414, 2433, 2433, 2433, 2433,
2433, 2433, 3414, 3414, 2433, 2433, 2433, 2433
},
{
1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195,
1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195,
1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281,
1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238,
1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195,
1195, 1195, 1195, 1195, 1195, 1195, 1195, 1195,
1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281,
1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281
},
{
2433, 2433, 2433, 2433, 2433, 2433, 2433, 2433,
2433, 2433, 2433, 2433, 2433, 2433, 2433, 2433,
3414, 3414, 3414, 3414, 3414, 3414, 3414, 3414,
3414, 3414, 3414, 3414, 3414, 3414, 3414, 3414,
2433, 2433, 2433, 2433, 2433, 2433, 2433, 2433,
2433, 2433, 2433, 2433, 2433, 2433, 2433, 2433,
2433, 2433, 2433, 2433, 2433, 2433, 2433, 2433,
2433, 2433, 2433, 2433, 2433, 2433, 2433, 2433
},
{
1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707,
1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707,
1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707,
1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707,
1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707,
1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707,
1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707,
1707, 1707, 1707, 1707, 1707, 1707, 1707, 1707
},
{
86, 171, 171, 214, 214, 214, 214, 257,
171, 171, 214, 214, 214, 214, 257, 257,
171, 214, 214, 214, 214, 257, 257, 257,
214, 214, 214, 214, 257, 257, 257, 299,
214, 214, 214, 257, 257, 257, 299, 299,
214, 214, 257, 257, 257, 299, 299, 299,
214, 257, 257, 257, 299, 299, 299, 342,
257, 257, 257, 299, 299, 299, 342, 342
},
{
854, 854, 1195, 1195, 1707, 1707, 1707, 1707,
854, 854, 1195, 1195, 1707, 1707, 1707, 1707,
1195, 1195, 1707, 1707, 2390, 2390, 2390, 2390,
1195, 1195, 1707, 1707, 2390, 2390, 2390, 2390,
1707, 1707, 2390, 2390, 1707, 1707, 1707, 1707,
1707, 1707, 2390, 2390, 1707, 1707, 1707, 1707,
1707, 1707, 2390, 2390, 1707, 1707, 1707, 1707,
1707, 1707, 2390, 2390, 1707, 1707, 1707, 1707
}
};

static uint16_t ivi4_quant_4x4_intra[5][16] = {
{
22, 214, 257, 299,
214, 257, 299, 342,
257, 299, 342, 427,
299, 342, 427, 513
},
{
129, 1025, 1451, 1451,
1025, 1025, 1451, 1451,
1451, 1451, 2049, 2049,
1451, 1451, 2049, 2049
},
{
43, 171, 171, 171,
43, 171, 171, 171,
43, 171, 171, 171,
43, 171, 171, 171
},
{
43, 43, 43, 43,
171, 171, 171, 171,
171, 171, 171, 171,
171, 171, 171, 171
},
{
43, 43, 43, 43,
43, 43, 43, 43,
43, 43, 43, 43,
43, 43, 43, 43
}
};

static uint16_t ivi4_quant_4x4_inter[5][16] = {
{
107, 214, 257, 299,
214, 257, 299, 299,
257, 299, 299, 342,
299, 299, 342, 342
},
{
513, 1025, 1238, 1238,
1025, 1025, 1238, 1238,
1238, 1238, 1451, 1451,
1238, 1238, 1451, 1451
},
{
43, 171, 171, 171,
43, 171, 171, 171,
43, 171, 171, 171,
43, 171, 171, 171
},
{
43, 43, 43, 43,
171, 171, 171, 171,
171, 171, 171, 171,
171, 171, 171, 171
},
{
43, 43, 43, 43,
43, 43, 43, 43,
43, 43, 43, 43,
43, 43, 43, 43
}
};

/**
* Table for mapping quant matrix index from the bitstream
* into internal quant table number.
*/
static uint8_t quant_index_to_tab[22] = {
0, 1, 0, 2, 1, 3, 0, 4, 1, 5, 0, 1, 6, 7, 8, // for 8x8 quant matrixes
0, 1, 2, 2, 3, 3, 4 // for 4x4 quant matrixes
};

#endif /* AVCODEC_INDEO4DATA_H */
17 changes: 9 additions & 8 deletions libavcodec/indeo5.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ typedef struct {
*/
static int decode_gop_header(IVI5DecContext *ctx, AVCodecContext *avctx)
{
int result, i, p, tile_size, pic_size_indx, mb_size, blk_size;
int result, i, p, tile_size, pic_size_indx, mb_size, blk_size, is_scalable;
int quant_mat, blk_size_changed = 0;
IVIBandDesc *band, *band1, *band2;
IVIPicConfig pic_conf;
Expand All @@ -112,8 +112,8 @@ static int decode_gop_header(IVI5DecContext *ctx, AVCodecContext *avctx)
/* num_levels * 3 + 1 */
pic_conf.luma_bands = get_bits(&ctx->gb, 2) * 3 + 1;
pic_conf.chroma_bands = get_bits1(&ctx->gb) * 3 + 1;
ctx->is_scalable = pic_conf.luma_bands != 1 || pic_conf.chroma_bands != 1;
if (ctx->is_scalable && (pic_conf.luma_bands != 4 || pic_conf.chroma_bands != 1)) {
is_scalable = pic_conf.luma_bands != 1 || pic_conf.chroma_bands != 1;
if (is_scalable && (pic_conf.luma_bands != 4 || pic_conf.chroma_bands != 1)) {
av_log(avctx, AV_LOG_ERROR, "Scalability: unsupported subdivision! Luma bands: %d, chroma bands: %d\n",
pic_conf.luma_bands, pic_conf.chroma_bands);
return -1;
Expand Down Expand Up @@ -151,6 +151,7 @@ static int decode_gop_header(IVI5DecContext *ctx, AVCodecContext *avctx)
return -1;
}
ctx->pic_conf = pic_conf;
ctx->is_scalable = is_scalable;
blk_size_changed = 1; /* force reallocation of the internal structures */
}

Expand Down Expand Up @@ -481,7 +482,7 @@ static int decode_mb_info(IVI5DecContext *ctx, IVIBandDesc *band,
}

mb->mv_x = mb->mv_y = 0; /* no motion vector coded */
if (band->inherit_mv){
if (band->inherit_mv && ref_mb){
/* motion vector inheritance */
if (mv_scale) {
mb->mv_x = ivi_scale_mv(ref_mb->mv_x, mv_scale);
Expand All @@ -492,7 +493,7 @@ static int decode_mb_info(IVI5DecContext *ctx, IVIBandDesc *band,
}
}
} else {
if (band->inherit_mv) {
if (band->inherit_mv && ref_mb) {
mb->type = ref_mb->type; /* copy mb_type from corresponding reference mb */
} else if (ctx->frame_type == FRAMETYPE_INTRA) {
mb->type = 0; /* mb_type is always INTRA for intra-frames */
Expand All @@ -518,7 +519,7 @@ static int decode_mb_info(IVI5DecContext *ctx, IVIBandDesc *band,
if (!mb->type) {
mb->mv_x = mb->mv_y = 0; /* there is no motion vector in intra-macroblocks */
} else {
if (band->inherit_mv){
if (band->inherit_mv && ref_mb){
/* motion vector inheritance */
if (mv_scale) {
mb->mv_x = ivi_scale_mv(ref_mb->mv_x, mv_scale);
Expand Down Expand Up @@ -759,7 +760,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,

switch_buffers(ctx);

//START_TIMER;
//{ START_TIMER;

if (ctx->frame_type != FRAMETYPE_NULL) {
for (p = 0; p < 3; p++) {
Expand All @@ -774,7 +775,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
}
}

//STOP_TIMER("decode_planes");
//STOP_TIMER("decode_planes"); }

if (ctx->frame.data[0])
avctx->release_buffer(avctx, &ctx->frame);
Expand Down
4 changes: 3 additions & 1 deletion libavcodec/ivi_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,8 @@ int av_cold ff_ivi_init_tiles(IVIPlaneDesc *planes, int tile_width, int tile_hei
t_width >>= 1;
t_height >>= 1;
}
if(t_width<=0 || t_height<=0)
return AVERROR(EINVAL);

for (b = 0; b < planes[p].num_bands; b++) {
band = &planes[p].bands[b];
Expand Down Expand Up @@ -506,7 +508,7 @@ void ff_ivi_process_empty_tile(AVCodecContext *avctx, IVIBandDesc *band,
if (band->inherit_qdelta && ref_mb)
mb->q_delta = ref_mb->q_delta;

if (band->inherit_mv) {
if (band->inherit_mv && ref_mb) {
/* motion vector inheritance */
if (mv_scale) {
mb->mv_x = ivi_scale_mv(ref_mb->mv_x, mv_scale);
Expand Down
8 changes: 4 additions & 4 deletions libavcodec/ivi_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -195,10 +195,10 @@ typedef struct {
/** compare some properties of two pictures */
static inline int ivi_pic_config_cmp(IVIPicConfig *str1, IVIPicConfig *str2)
{
return (str1->pic_width != str2->pic_width || str1->pic_height != str2->pic_height ||
str1->chroma_width != str2->chroma_width || str1->chroma_height != str2->chroma_height ||
str1->tile_width != str2->tile_width || str1->tile_height != str2->tile_height ||
str1->luma_bands != str2->luma_bands || str1->chroma_bands != str2->chroma_bands);
return str1->pic_width != str2->pic_width || str1->pic_height != str2->pic_height ||
str1->chroma_width != str2->chroma_width || str1->chroma_height != str2->chroma_height ||
str1->tile_width != str2->tile_width || str1->tile_height != str2->tile_height ||
str1->luma_bands != str2->luma_bands || str1->chroma_bands != str2->chroma_bands;
}

/** calculate number of tiles in a stride */
Expand Down
149 changes: 148 additions & 1 deletion libavcodec/ivi_dsp.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* DSP functions for Indeo Video Interactive codecs (Indeo4 and Indeo5)
*
* Copyright (c) 2009 Maxim Poliakovski
* Copyright (c) 2009-2011 Maxim Poliakovski
*
* This file is part of FFmpeg.
*
Expand Down Expand Up @@ -178,6 +178,153 @@ void ff_ivi_recompose53(const IVIPlaneDesc *plane, uint8_t *dst,
}
}

void ff_ivi_recompose_haar(const IVIPlaneDesc *plane, uint8_t *dst,
const int dst_pitch, const int num_bands)
{
int x, y, indx, b0, b1, b2, b3, p0, p1, p2, p3;
const IDWTELEM *b0_ptr, *b1_ptr, *b2_ptr, *b3_ptr;
int32_t pitch;

/* all bands should have the same pitch */
pitch = plane->bands[0].pitch;

/* get pointers to the wavelet bands */
b0_ptr = plane->bands[0].buf;
b1_ptr = plane->bands[1].buf;
b2_ptr = plane->bands[2].buf;
b3_ptr = plane->bands[3].buf;

for (y = 0; y < plane->height; y += 2) {
for (x = 0, indx = 0; x < plane->width; x += 2, indx++) {
/* load coefficients */
b0 = b0_ptr[indx]; //should be: b0 = (num_bands > 0) ? b0_ptr[indx] : 0;
b1 = b1_ptr[indx]; //should be: b1 = (num_bands > 1) ? b1_ptr[indx] : 0;
b2 = b2_ptr[indx]; //should be: b2 = (num_bands > 2) ? b2_ptr[indx] : 0;
b3 = b3_ptr[indx]; //should be: b3 = (num_bands > 3) ? b3_ptr[indx] : 0;

/* haar wavelet recomposition */
p0 = (b0 + b1 + b2 + b3 + 2) >> 2;
p1 = (b0 + b1 - b2 - b3 + 2) >> 2;
p2 = (b0 - b1 + b2 - b3 + 2) >> 2;
p3 = (b0 - b1 - b2 + b3 + 2) >> 2;

/* bias, convert and output four pixels */
dst[x] = av_clip_uint8(p0 + 128);
dst[x + 1] = av_clip_uint8(p1 + 128);
dst[dst_pitch + x] = av_clip_uint8(p2 + 128);
dst[dst_pitch + x + 1] = av_clip_uint8(p3 + 128);
}// for x

dst += dst_pitch << 1;

b0_ptr += pitch;
b1_ptr += pitch;
b2_ptr += pitch;
b3_ptr += pitch;
}// for y
}

/** butterfly operation for the inverse Haar transform */
#define IVI_HAAR_BFLY(s1, s2, o1, o2, t) \
t = (s1 - s2) >> 1;\
o1 = (s1 + s2) >> 1;\
o2 = t;\

/** inverse 8-point Haar transform */
#define INV_HAAR8(s1, s5, s3, s7, s2, s4, s6, s8,\
d1, d2, d3, d4, d5, d6, d7, d8,\
t0, t1, t2, t3, t4, t5, t6, t7, t8) {\
t1 = s1 << 1; t5 = s5 << 1;\
IVI_HAAR_BFLY(t1, t5, t1, t5, t0); IVI_HAAR_BFLY(t1, s3, t1, t3, t0);\
IVI_HAAR_BFLY(t5, s7, t5, t7, t0); IVI_HAAR_BFLY(t1, s2, t1, t2, t0);\
IVI_HAAR_BFLY(t3, s4, t3, t4, t0); IVI_HAAR_BFLY(t5, s6, t5, t6, t0);\
IVI_HAAR_BFLY(t7, s8, t7, t8, t0);\
d1 = COMPENSATE(t1);\
d2 = COMPENSATE(t2);\
d3 = COMPENSATE(t3);\
d4 = COMPENSATE(t4);\
d5 = COMPENSATE(t5);\
d6 = COMPENSATE(t6);\
d7 = COMPENSATE(t7);\
d8 = COMPENSATE(t8); }

/** inverse 4-point Haar transform */
#define INV_HAAR4(s1, s3, s5, s7) {\
HAAR_BFLY(s1, s5); HAAR_BFLY(s1, s3); HAAR_BFLY(s5, s7);\
s1 = COMPENSATE(s1);\
s3 = COMPENSATE(s3);\
s5 = COMPENSATE(s5);\
s7 = COMPENSATE(s7); }

void ff_ivi_inverse_haar_8x8(const int32_t *in, int16_t *out, uint32_t pitch,
const uint8_t *flags)
{
int i, shift, sp1, sp2, sp3, sp4;
const int32_t *src;
int32_t *dst;
int tmp[64];
int t0, t1, t2, t3, t4, t5, t6, t7, t8;

/* apply the InvHaar8 to all columns */
#define COMPENSATE(x) (x)
src = in;
dst = tmp;
for (i = 0; i < 8; i++) {
if (flags[i]) {
/* pre-scaling */
shift = !(i & 4);
sp1 = src[ 0] << shift;
sp2 = src[ 8] << shift;
sp3 = src[16] << shift;
sp4 = src[24] << shift;
INV_HAAR8( sp1, sp2, sp3, sp4,
src[32], src[40], src[48], src[56],
dst[ 0], dst[ 8], dst[16], dst[24],
dst[32], dst[40], dst[48], dst[56],
t0, t1, t2, t3, t4, t5, t6, t7, t8);
} else
dst[ 0] = dst[ 8] = dst[16] = dst[24] =
dst[32] = dst[40] = dst[48] = dst[56] = 0;

src++;
dst++;
}
#undef COMPENSATE

/* apply the InvHaar8 to all rows */
#define COMPENSATE(x) (x)
src = tmp;
for (i = 0; i < 8; i++) {
if ( !src[0] && !src[1] && !src[2] && !src[3]
&& !src[4] && !src[5] && !src[6] && !src[7]) {
memset(out, 0, 8 * sizeof(out[0]));
} else {
INV_HAAR8(src[0], src[1], src[2], src[3],
src[4], src[5], src[6], src[7],
out[0], out[1], out[2], out[3],
out[4], out[5], out[6], out[7],
t0, t1, t2, t3, t4, t5, t6, t7, t8);
}
src += 8;
out += pitch;
}
#undef COMPENSATE
}

void ff_ivi_dc_haar_2d(const int32_t *in, int16_t *out, uint32_t pitch,
int blk_size)
{
int x, y;
int16_t dc_coeff;

dc_coeff = (*in + 0) >> 3;

for (y = 0; y < blk_size; out += pitch, y++) {
for (x = 0; x < blk_size; x++)
out[x] = dc_coeff;
}
}

/** butterfly operation for the inverse slant transform */
#define IVI_SLANT_BFLY(s1, s2, o1, o2, t) \
t = s1 - s2;\
Expand Down
39 changes: 38 additions & 1 deletion libavcodec/ivi_dsp.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* DSP functions for Indeo Video Interactive codecs (Indeo4 and Indeo5)
*
* Copyright (c) 2009 Maxim Poliakovski
* Copyright (c) 2009-2011 Maxim Poliakovski
*
* This file is part of FFmpeg.
*
Expand Down Expand Up @@ -43,6 +43,43 @@
void ff_ivi_recompose53(const IVIPlaneDesc *plane, uint8_t *dst,
const int dst_pitch, const int num_bands);

/**
* Haar wavelet recomposition filter for Indeo 4
*
* @param[in] plane pointer to the descriptor of the plane being processed
* @param[out] dst pointer to the destination buffer
* @param[in] dst_pitch pitch of the destination buffer
* @param[in] num_bands number of wavelet bands to be processed
*/
void ff_ivi_recompose_haar(const IVIPlaneDesc *plane, uint8_t *dst,
const int dst_pitch, const int num_bands);

/**
* two-dimensional inverse Haar 8x8 transform for Indeo 4
*
* @param[in] in pointer to the vector of transform coefficients
* @param[out] out pointer to the output buffer (frame)
* @param[in] pitch pitch to move to the next y line
* @param[in] flags pointer to the array of column flags:
* != 0 - non_empty column, 0 - empty one
* (this array must be filled by caller)
*/
void ff_ivi_inverse_haar_8x8(const int32_t *in, int16_t *out, uint32_t pitch,
const uint8_t *flags);

/**
* DC-only two-dimensional inverse Haar transform for Indeo 4.
* Performing the inverse transform in this case is equivalent to
* spreading DC_coeff >> 3 over the whole block.
*
* @param[in] in pointer to the dc coefficient
* @param[out] out pointer to the output buffer (frame)
* @param[in] pitch pitch to move to the next y line
* @param[in] blk_size transform block size
*/
void ff_ivi_dc_haar_2d(const int32_t *in, int16_t *out, uint32_t pitch,
int blk_size);

/**
* two-dimensional inverse slant 8x8 transform
*
Expand Down
21 changes: 10 additions & 11 deletions libavcodec/j2kdec.c
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ static int get_siz(J2kDecoderContext *s)
if ((ret = s->avctx->get_buffer(s->avctx, &s->picture)) < 0)
return ret;

s->picture.pict_type = FF_I_TYPE;
s->picture.pict_type = AV_PICTURE_TYPE_I;
s->picture.key_frame = 1;

return 0;
Expand Down Expand Up @@ -921,7 +921,7 @@ static int decode_codestream(J2kDecoderContext *s)

marker = bytestream_get_be16(&s->buf);
if(s->avctx->debug & FF_DEBUG_STARTCODE)
av_log(s->avctx, AV_LOG_DEBUG, "marker 0x%.4X at pos 0x%x\n", marker, s->buf - s->buf_start - 4);
av_log(s->avctx, AV_LOG_DEBUG, "marker 0x%.4X at pos 0x%tx\n", marker, s->buf - s->buf_start - 4);
oldbuf = s->buf;

if (marker == J2K_SOD){
Expand Down Expand Up @@ -1068,16 +1068,15 @@ static av_cold int decode_end(AVCodecContext *avctx)
}

AVCodec ff_jpeg2000_decoder = {
"j2k",
AVMEDIA_TYPE_VIDEO,
CODEC_ID_JPEG2000,
sizeof(J2kDecoderContext),
j2kdec_init,
NULL,
decode_end,
decode_frame,
.name = "j2k",
.type = AVMEDIA_TYPE_VIDEO,
.id = CODEC_ID_JPEG2000,
.priv_data_size = sizeof(J2kDecoderContext),
.init = j2kdec_init,
.close = decode_end,
.decode = decode_frame,
.capabilities = CODEC_CAP_EXPERIMENTAL,
.long_name = NULL_IF_CONFIG_SMALL("JPEG 2000"),
.pix_fmts =
(enum PixelFormat[]) {PIX_FMT_GRAY8, PIX_FMT_RGB24, -1}
(enum PixelFormat[]) {PIX_FMT_GRAY8, PIX_FMT_RGB24, PIX_FMT_NONE}
};
14 changes: 7 additions & 7 deletions libavcodec/j2kenc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1036,13 +1036,13 @@ static int j2kenc_destroy(AVCodecContext *avctx)
}

AVCodec ff_jpeg2000_encoder = {
"j2k",
AVMEDIA_TYPE_VIDEO,
CODEC_ID_JPEG2000,
sizeof(J2kEncoderContext),
j2kenc_init,
encode_frame,
j2kenc_destroy,
.name = "j2k",
.type = AVMEDIA_TYPE_VIDEO,
.id = CODEC_ID_JPEG2000,
.priv_data_size = sizeof(J2kEncoderContext),
.init = j2kenc_init,
.encode = encode_frame,
.close = j2kenc_destroy,
.capabilities= CODEC_CAP_EXPERIMENTAL,
.long_name = NULL_IF_CONFIG_SMALL("JPEG 2000"),
.pix_fmts =
Expand Down
8 changes: 7 additions & 1 deletion libavcodec/lcldec.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,13 @@ static unsigned int mszh_decomp(const unsigned char * srcptr, int srclen, unsign
ofs = FFMIN(ofs, destptr - destptr_bak);
cnt *= 4;
cnt = FFMIN(cnt, destptr_end - destptr);
av_memcpy_backptr(destptr, ofs, cnt);
if (ofs) {
av_memcpy_backptr(destptr, ofs, cnt);
} else {
// Not known what the correct behaviour is, but
// this at least avoids uninitialized data.
memset(destptr, 0, cnt);
}
destptr += cnt;
}
maskbit >>= 1;
Expand Down
16 changes: 8 additions & 8 deletions libavcodec/libaacplus.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,13 +122,13 @@ static av_cold int aacPlus_encode_close(AVCodecContext *avctx)
}

AVCodec ff_libaacplus_encoder = {
"libaacplus",
AVMEDIA_TYPE_AUDIO,
CODEC_ID_AAC,
sizeof(aacPlusAudioContext),
aacPlus_encode_init,
aacPlus_encode_frame,
aacPlus_encode_close,
.sample_fmts = (const enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_NONE},
.name = "libaacplus",
.type = AVMEDIA_TYPE_AUDIO,
.id = CODEC_ID_AAC,
.priv_data_size = sizeof(aacPlusAudioContext),
.init = aacPlus_encode_init,
.encode = aacPlus_encode_frame,
.close = aacPlus_encode_close,
.sample_fmts = (const enum SampleFormat[]){AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE},
.long_name = NULL_IF_CONFIG_SMALL("libaacplus AAC+ (Advanced Audio Codec with SBR+PS)"),
};
139 changes: 72 additions & 67 deletions libavcodec/libmp3lame.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
#include "mpegaudio.h"
#include <lame/lame.h>

#define BUFFER_SIZE (7200 + 2*MPA_FRAME_SIZE + MPA_FRAME_SIZE/4)
#define BUFFER_SIZE (7200 + 2 * MPA_FRAME_SIZE + MPA_FRAME_SIZE / 4)
typedef struct Mp3AudioContext {
AVClass *class;
lame_global_flags *gfp;
Expand Down Expand Up @@ -62,17 +62,17 @@ static av_cold int MP3lame_encode_init(AVCodecContext *avctx)
lame_set_in_samplerate(s->gfp, avctx->sample_rate);
lame_set_out_samplerate(s->gfp, avctx->sample_rate);
lame_set_num_channels(s->gfp, avctx->channels);
if(avctx->compression_level == FF_COMPRESSION_DEFAULT) {
if (avctx->compression_level == FF_COMPRESSION_DEFAULT) {
lame_set_quality(s->gfp, 5);
} else {
lame_set_quality(s->gfp, avctx->compression_level);
}
lame_set_mode(s->gfp, s->stereo ? JOINT_STEREO : MONO);
lame_set_brate(s->gfp, avctx->bit_rate/1000);
if(avctx->flags & CODEC_FLAG_QSCALE) {
lame_set_brate(s->gfp, avctx->bit_rate / 1000);
if (avctx->flags & CODEC_FLAG_QSCALE) {
lame_set_brate(s->gfp, 0);
lame_set_VBR(s->gfp, vbr_default);
lame_set_VBR_quality(s->gfp, avctx->global_quality/(float)FF_QP2LAMBDA);
lame_set_VBR_quality(s->gfp, avctx->global_quality / (float)FF_QP2LAMBDA);
}
lame_set_bWriteVbrTag(s->gfp,0);
#if FF_API_LAME_GLOBAL_OPTS
Expand All @@ -82,14 +82,14 @@ static av_cold int MP3lame_encode_init(AVCodecContext *avctx)
if (lame_init_params(s->gfp) < 0)
goto err_close;

avctx->frame_size = lame_get_framesize(s->gfp);
avctx->frame_size = lame_get_framesize(s->gfp);

if(!(avctx->coded_frame= avcodec_alloc_frame())) {
lame_close(s->gfp);

return AVERROR(ENOMEM);
}
avctx->coded_frame->key_frame= 1;
avctx->coded_frame->key_frame = 1;

if(AV_SAMPLE_FMT_S32 == avctx->sample_fmt && s->stereo) {
int nelem = 2 * avctx->frame_size;
Expand Down Expand Up @@ -117,68 +117,70 @@ static const int sSampleRates[] = {
};

static const int sBitRates[2][3][15] = {
{ { 0, 32, 64, 96,128,160,192,224,256,288,320,352,384,416,448},
{ 0, 32, 48, 56, 64, 80, 96,112,128,160,192,224,256,320,384},
{ 0, 32, 40, 48, 56, 64, 80, 96,112,128,160,192,224,256,320}
{
{ 0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448 },
{ 0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384 },
{ 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320 }
},
{ { 0, 32, 48, 56, 64, 80, 96,112,128,144,160,176,192,224,256},
{ 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96,112,128,144,160},
{ 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96,112,128,144,160}
{
{ 0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256 },
{ 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160 },
{ 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160 }
},
};

static const int sSamplesPerFrame[2][3] =
{
{ 384, 1152, 1152 },
{ 384, 1152, 576 }
static const int sSamplesPerFrame[2][3] = {
{ 384, 1152, 1152 },
{ 384, 1152, 576 }
};

static const int sBitsPerSlot[3] = {
32,
8,
8
};
static const int sBitsPerSlot[3] = { 32, 8, 8 };

static int mp3len(void *data, int *samplesPerFrame, int *sampleRate)
{
uint32_t header = AV_RB32(data);
int layerID = 3 - ((header >> 17) & 0x03);
int bitRateID = ((header >> 12) & 0x0f);
uint32_t header = AV_RB32(data);
int layerID = 3 - ((header >> 17) & 0x03);
int bitRateID = ((header >> 12) & 0x0f);
int sampleRateID = ((header >> 10) & 0x03);
int bitsPerSlot = sBitsPerSlot[layerID];
int isPadded = ((header >> 9) & 0x01);
static int const mode_tab[4]= {2,3,1,0};
int mode= mode_tab[(header >> 19) & 0x03];
int mpeg_id= mode>0;
int bitsPerSlot = sBitsPerSlot[layerID];
int isPadded = ((header >> 9) & 0x01);
static int const mode_tab[4] = { 2, 3, 1, 0 };
int mode = mode_tab[(header >> 19) & 0x03];
int mpeg_id = mode > 0;
int temp0, temp1, bitRate;

if ( (( header >> 21 ) & 0x7ff) != 0x7ff || mode == 3 || layerID==3 || sampleRateID==3) {
if (((header >> 21) & 0x7ff) != 0x7ff || mode == 3 || layerID == 3 ||
sampleRateID == 3) {
return -1;
}

if(!samplesPerFrame) samplesPerFrame= &temp0;
if(!sampleRate ) sampleRate = &temp1;
if (!samplesPerFrame)
samplesPerFrame = &temp0;
if (!sampleRate)
sampleRate = &temp1;

// *isMono = ((header >> 6) & 0x03) == 0x03;
//*isMono = ((header >> 6) & 0x03) == 0x03;

*sampleRate = sSampleRates[sampleRateID]>>mode;
bitRate = sBitRates[mpeg_id][layerID][bitRateID] * 1000;
*sampleRate = sSampleRates[sampleRateID] >> mode;
bitRate = sBitRates[mpeg_id][layerID][bitRateID] * 1000;
*samplesPerFrame = sSamplesPerFrame[mpeg_id][layerID];
//av_log(NULL, AV_LOG_DEBUG, "sr:%d br:%d spf:%d l:%d m:%d\n", *sampleRate, bitRate, *samplesPerFrame, layerID, mode);
//av_log(NULL, AV_LOG_DEBUG,
// "sr:%d br:%d spf:%d l:%d m:%d\n",
// *sampleRate, bitRate, *samplesPerFrame, layerID, mode);

return *samplesPerFrame * bitRate / (bitsPerSlot * *sampleRate) + isPadded;
}

static int MP3lame_encode_frame(AVCodecContext *avctx,
unsigned char *frame, int buf_size, void *data)
static int MP3lame_encode_frame(AVCodecContext *avctx, unsigned char *frame,
int buf_size, void *data)
{
Mp3AudioContext *s = avctx->priv_data;
int len;
int lame_result;

/* lame 3.91 dies on '1-channel interleaved' data */

if(!data){
if (!data){
lame_result= lame_encode_flush(
s->gfp,
s->buffer + s->buffer_index,
Expand Down Expand Up @@ -237,32 +239,35 @@ static int MP3lame_encode_frame(AVCodecContext *avctx,
}
}

if(lame_result < 0){
if(lame_result==-1) {
if (lame_result < 0) {
if (lame_result == -1) {
/* output buffer too small */
av_log(avctx, AV_LOG_ERROR, "lame: output buffer too small (buffer index: %d, free bytes: %d)\n", s->buffer_index, BUFFER_SIZE - s->buffer_index);
av_log(avctx, AV_LOG_ERROR,
"lame: output buffer too small (buffer index: %d, free bytes: %d)\n",
s->buffer_index, BUFFER_SIZE - s->buffer_index);
}
return -1;
}

s->buffer_index += lame_result;

if(s->buffer_index<4)
if (s->buffer_index < 4)
return 0;

len= mp3len(s->buffer, NULL, NULL);
//av_log(avctx, AV_LOG_DEBUG, "in:%d packet-len:%d index:%d\n", avctx->frame_size, len, s->buffer_index);
if(len <= s->buffer_index){
len = mp3len(s->buffer, NULL, NULL);
//av_log(avctx, AV_LOG_DEBUG, "in:%d packet-len:%d index:%d\n",
// avctx->frame_size, len, s->buffer_index);
if (len <= s->buffer_index) {
memcpy(frame, s->buffer, len);
s->buffer_index -= len;

memmove(s->buffer, s->buffer+len, s->buffer_index);
//FIXME fix the audio codec API, so we do not need the memcpy()
/*for(i=0; i<len; i++){
av_log(avctx, AV_LOG_DEBUG, "%2X ", frame[i]);
}*/
memmove(s->buffer, s->buffer + len, s->buffer_index);
// FIXME fix the audio codec API, so we do not need the memcpy()
/*for(i=0; i<len; i++) {
av_log(avctx, AV_LOG_DEBUG, "%2X ", frame[i]);
}*/
return len;
}else
} else
return 0;
}

Expand All @@ -280,7 +285,7 @@ static av_cold int MP3lame_encode_close(AVCodecContext *avctx)
#define OFFSET(x) offsetof(Mp3AudioContext, x)
#define AE AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
static const AVOption options[] = {
{ "reservoir", "Use bit reservoir.", OFFSET(reservoir), AV_OPT_TYPE_INT, { 1 }, 0, 1, AE },
{ "reservoir", "Use bit reservoir.", OFFSET(reservoir), AV_OPT_TYPE_INT, { 1 }, 0, 1, AE },
{ NULL },
};

Expand All @@ -292,20 +297,20 @@ static const AVClass libmp3lame_class = {
};

AVCodec ff_libmp3lame_encoder = {
.name = "libmp3lame",
.type = AVMEDIA_TYPE_AUDIO,
.id = CODEC_ID_MP3,
.priv_data_size = sizeof(Mp3AudioContext),
.init = MP3lame_encode_init,
.encode = MP3lame_encode_frame,
.close = MP3lame_encode_close,
.capabilities= CODEC_CAP_DELAY,
.sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,
.name = "libmp3lame",
.type = AVMEDIA_TYPE_AUDIO,
.id = CODEC_ID_MP3,
.priv_data_size = sizeof(Mp3AudioContext),
.init = MP3lame_encode_init,
.encode = MP3lame_encode_frame,
.close = MP3lame_encode_close,
.capabilities = CODEC_CAP_DELAY,
.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16,
#if 2147483647 == INT_MAX
AV_SAMPLE_FMT_S32,
#endif
AV_SAMPLE_FMT_NONE},
.supported_samplerates= sSampleRates,
.long_name= NULL_IF_CONFIG_SMALL("libmp3lame MP3 (MPEG audio layer 3)"),
.priv_class = &libmp3lame_class,
AV_SAMPLE_FMT_NONE },
.supported_samplerates = sSampleRates,
.long_name = NULL_IF_CONFIG_SMALL("libmp3lame MP3 (MPEG audio layer 3)"),
.priv_class = &libmp3lame_class,
};
17 changes: 14 additions & 3 deletions libavcodec/libopenjpegdec.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ static enum PixelFormat check_image_attributes(AVCodecContext *avctx, opj_image_

switch (compRatio) {
case 0111111: goto libopenjpeg_yuv444_rgb;
case 0111212: return PIX_FMT_YUV440P;
case 0112121: goto libopenjpeg_yuv422;
case 0112222: goto libopenjpeg_yuv420;
default: goto libopenjpeg_rgb;
Expand Down Expand Up @@ -90,6 +91,15 @@ static enum PixelFormat check_image_attributes(AVCodecContext *avctx, opj_image_
return PIX_FMT_RGB24;
}

static int is_yuva420(opj_image_t *image)
{
return image->numcomps == 4 &&
image->comps[0].dx == 1 && image->comps[0].dy == 1 &&
image->comps[1].dx == 2 && image->comps[1].dy == 2 &&
image->comps[2].dx == 2 && image->comps[2].dy == 2 &&
image->comps[3].dx == 1 && image->comps[3].dy == 1;
}

static inline int libopenjpeg_ispacked(enum PixelFormat pix_fmt) {
int i, component_plane;
component_plane = av_pix_fmt_descriptors[pix_fmt].comp[0].plane;
Expand Down Expand Up @@ -139,8 +149,8 @@ static inline void libopenjpeg_copyto8(AVFrame *picture, opj_image_t *image) {

for(index = 0; index < image->numcomps; index++) {
comp_data = image->comps[index].data;
img_ptr = picture->data[index];
for(y = 0; y < image->comps[index].h; y++) {
img_ptr = picture->data[index] + y * picture->linesize[index];
for(x = 0; x < image->comps[index].w; x++) {
*img_ptr = (uint8_t) *comp_data;
img_ptr++;
Expand All @@ -156,8 +166,8 @@ static inline void libopenjpeg_copyto16(AVFrame *picture, opj_image_t *image) {
int index, x, y;
for(index = 0; index < image->numcomps; index++) {
comp_data = image->comps[index].data;
img_ptr = (uint16_t*) picture->data[index];
for(y = 0; y < image->comps[index].h; y++) {
img_ptr = (uint16_t*) (picture->data[index] + y * picture->linesize[index]);
for(x = 0; x < image->comps[index].w; x++) {
*img_ptr = *comp_data;
img_ptr++;
Expand Down Expand Up @@ -252,7 +262,7 @@ static int libopenjpeg_decode_frame(AVCodecContext *avctx,
break;
case 3: avctx->pix_fmt = check_image_attributes(avctx, image);
break;
case 4: avctx->pix_fmt = PIX_FMT_RGBA;
case 4: avctx->pix_fmt = is_yuva420(image) ? PIX_FMT_YUVA420P : PIX_FMT_RGBA;
break;
default: av_log(avctx, AV_LOG_ERROR, "%d components unsupported.\n", image->numcomps);
goto done;
Expand Down Expand Up @@ -296,6 +306,7 @@ static int libopenjpeg_decode_frame(AVCodecContext *avctx,
libopenjpeg_copyto16(picture, image);
break;
case 3:
case 4:
if (ispacked) {
libopenjpeg_copy_to_packed8(picture, image);
}
Expand Down
4 changes: 2 additions & 2 deletions libavcodec/libopenjpegenc.c
Original file line number Diff line number Diff line change
Expand Up @@ -365,13 +365,13 @@ AVCodec ff_libopenjpeg_encoder = {
.init = libopenjpeg_encode_init,
.encode = libopenjpeg_encode_frame,
.close = libopenjpeg_encode_close,
.decode = NULL,
.capabilities = 0,
.pix_fmts = (const enum PixelFormat[]){PIX_FMT_RGB24,PIX_FMT_RGBA,PIX_FMT_GRAY8,
PIX_FMT_YUV420P,PIX_FMT_YUV422P,PIX_FMT_YUVA420P,
PIX_FMT_YUV440P,PIX_FMT_YUV444P,
PIX_FMT_YUV420P9,PIX_FMT_YUV422P9,PIX_FMT_YUV444P9,
PIX_FMT_YUV420P10,PIX_FMT_YUV422P10,PIX_FMT_YUV444P10,
PIX_FMT_YUV420P16,PIX_FMT_YUV422P16,PIX_FMT_YUV444P16},
PIX_FMT_YUV420P16,PIX_FMT_YUV422P16,PIX_FMT_YUV444P16,
PIX_FMT_NONE},
.long_name = NULL_IF_CONFIG_SMALL("OpenJPEG based JPEG 2000 encoder"),
} ;
12 changes: 7 additions & 5 deletions libavcodec/libspeexenc.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ typedef struct {
int abr; ///< flag to enable ABR
int pkt_frame_count; ///< frame count for the current packet
int lookahead; ///< encoder delay
int sample_count; ///< total sample count (used for pts)
int64_t next_pts; ///< next pts, in sample_rate time base
int pkt_sample_count; ///< sample count in the current packet
} LibSpeexEncContext;

static av_cold void print_enc_params(AVCodecContext *avctx,
Expand Down Expand Up @@ -201,7 +202,7 @@ static av_cold int encode_init(AVCodecContext *avctx)

/* set encoding delay */
speex_encoder_ctl(s->enc_state, SPEEX_GET_LOOKAHEAD, &s->lookahead);
s->sample_count = -s->lookahead;
s->next_pts = -s->lookahead;

/* create header packet bytes from header struct */
/* note: libspeex allocates the memory for header_data, which is freed
Expand Down Expand Up @@ -235,15 +236,14 @@ static int encode_frame(AVCodecContext *avctx, uint8_t *frame, int buf_size,
{
LibSpeexEncContext *s = avctx->priv_data;
int16_t *samples = data;
int sample_count = s->sample_count;

if (data) {
/* encode Speex frame */
if (avctx->channels == 2)
speex_encode_stereo_int(samples, s->header.frame_size, &s->bits);
speex_encode_int(s->enc_state, samples, &s->bits);
s->pkt_frame_count++;
s->sample_count += avctx->frame_size;
s->pkt_sample_count += avctx->frame_size;
} else {
/* handle end-of-stream */
if (!s->pkt_frame_count)
Expand All @@ -259,8 +259,10 @@ static int encode_frame(AVCodecContext *avctx, uint8_t *frame, int buf_size,
if (s->pkt_frame_count == s->frames_per_packet) {
s->pkt_frame_count = 0;
avctx->coded_frame->pts =
av_rescale_q(sample_count, (AVRational){ 1, avctx->sample_rate },
av_rescale_q(s->next_pts, (AVRational){ 1, avctx->sample_rate },
avctx->time_base);
s->next_pts += s->pkt_sample_count;
s->pkt_sample_count = 0;
if (buf_size > speex_bits_nbytes(&s->bits)) {
int ret = speex_bits_write(&s->bits, frame, buf_size);
speex_bits_reset(&s->bits);
Expand Down
191 changes: 110 additions & 81 deletions libavcodec/libvorbis.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,63 +37,86 @@

#define OGGVORBIS_FRAME_SIZE 64

#define BUFFER_SIZE (1024*64)
#define BUFFER_SIZE (1024 * 64)

typedef struct OggVorbisContext {
AVClass *av_class;
vorbis_info vi ;
vorbis_dsp_state vd ;
vorbis_block vb ;
vorbis_info vi;
vorbis_dsp_state vd;
vorbis_block vb;
uint8_t buffer[BUFFER_SIZE];
int buffer_index;
int eof;

/* decoder */
vorbis_comment vc ;
vorbis_comment vc;
ogg_packet op;

double iblock;
} OggVorbisContext ;
} OggVorbisContext;

static const AVOption options[]={
{"iblock", "Sets the impulse block bias", offsetof(OggVorbisContext, iblock), AV_OPT_TYPE_DOUBLE, {.dbl = 0}, -15, 0, AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_ENCODING_PARAM},
{NULL}
static const AVOption options[] = {
{ "iblock", "Sets the impulse block bias", offsetof(OggVorbisContext, iblock), AV_OPT_TYPE_DOUBLE, { .dbl = 0 }, -15, 0, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM },
{ NULL }
};
static const AVClass class = { "libvorbis", av_default_item_name, options, LIBAVUTIL_VERSION_INT };

static av_cold int oggvorbis_init_encoder(vorbis_info *vi, AVCodecContext *avccontext) {
OggVorbisContext *context = avccontext->priv_data ;
static const char * error(int oggerr, int *averr)
{
switch (oggerr) {
case OV_EFAULT: *averr = AVERROR(EFAULT); return "internal error";
case OV_EIMPL: *averr = AVERROR(EINVAL); return "not supported";
case OV_EINVAL: *averr = AVERROR(EINVAL); return "invalid request";
default: *averr = AVERROR(EINVAL); return "unknown error";
}
}

static av_cold int oggvorbis_init_encoder(vorbis_info *vi, AVCodecContext *avccontext)
{
OggVorbisContext *context = avccontext->priv_data;
double cfreq;
int r;

if(avccontext->flags & CODEC_FLAG_QSCALE) {
if (avccontext->flags & CODEC_FLAG_QSCALE) {
/* variable bitrate */
if(vorbis_encode_setup_vbr(vi, avccontext->channels,
avccontext->sample_rate,
avccontext->global_quality / (float)FF_QP2LAMBDA / 10.0))
return -1;
float quality = avccontext->global_quality / (float)FF_QP2LAMBDA;
r = vorbis_encode_setup_vbr(vi, avccontext->channels,
avccontext->sample_rate,
quality / 10.0);
if (r) {
av_log(avccontext, AV_LOG_ERROR,
"Unable to set quality to %g: %s\n", quality, error(r, &r));
return r;
}
} else {
int minrate = avccontext->rc_min_rate > 0 ? avccontext->rc_min_rate : -1;
int maxrate = avccontext->rc_min_rate > 0 ? avccontext->rc_max_rate : -1;

/* constant bitrate */
if(vorbis_encode_setup_managed(vi, avccontext->channels,
avccontext->sample_rate, minrate, avccontext->bit_rate, maxrate))
return -1;
r = vorbis_encode_setup_managed(vi, avccontext->channels,
avccontext->sample_rate, minrate,
avccontext->bit_rate, maxrate);
if (r) {
av_log(avccontext, AV_LOG_ERROR,
"Unable to set CBR to %d: %s\n", avccontext->bit_rate,
error(r, &r));
return r;
}

/* variable bitrate by estimate, disable slow rate management */
if(minrate == -1 && maxrate == -1)
if(vorbis_encode_ctl(vi, OV_ECTL_RATEMANAGE2_SET, NULL))
return -1;
if (minrate == -1 && maxrate == -1)
if (vorbis_encode_ctl(vi, OV_ECTL_RATEMANAGE2_SET, NULL))
return AVERROR(EINVAL); /* should not happen */
}

/* cutoff frequency */
if(avccontext->cutoff > 0) {
if (avccontext->cutoff > 0) {
cfreq = avccontext->cutoff / 1000.0;
if(vorbis_encode_ctl(vi, OV_ECTL_LOWPASS_SET, &cfreq))
return -1;
if (vorbis_encode_ctl(vi, OV_ECTL_LOWPASS_SET, &cfreq))
return AVERROR(EINVAL); /* should not happen */
}

if(context->iblock){
if (context->iblock) {
vorbis_encode_ctl(vi, OV_ECTL_IBLOCK_SET, &context->iblock);
}

Expand Down Expand Up @@ -130,35 +153,41 @@ static av_cold int oggvorbis_init_encoder(vorbis_info *vi, AVCodecContext *avcco
}

/* How many bytes are needed for a buffer of length 'l' */
static int xiph_len(int l) { return (1 + l / 255 + l); }
static int xiph_len(int l)
{
return 1 + l / 255 + l;
}

static av_cold int oggvorbis_encode_init(AVCodecContext *avccontext) {
OggVorbisContext *context = avccontext->priv_data ;
static av_cold int oggvorbis_encode_init(AVCodecContext *avccontext)
{
OggVorbisContext *context = avccontext->priv_data;
ogg_packet header, header_comm, header_code;
uint8_t *p;
unsigned int offset;
int r;

vorbis_info_init(&context->vi) ;
if(oggvorbis_init_encoder(&context->vi, avccontext) < 0) {
av_log(avccontext, AV_LOG_ERROR, "oggvorbis_encode_init: init_encoder failed\n") ;
return -1 ;
vorbis_info_init(&context->vi);
r = oggvorbis_init_encoder(&context->vi, avccontext);
if (r < 0) {
av_log(avccontext, AV_LOG_ERROR, "oggvorbis_encode_init failed\n");
return r;
}
vorbis_analysis_init(&context->vd, &context->vi) ;
vorbis_block_init(&context->vd, &context->vb) ;
vorbis_analysis_init(&context->vd, &context->vi);
vorbis_block_init(&context->vd, &context->vb);

vorbis_comment_init(&context->vc);
vorbis_comment_add_tag(&context->vc, "encoder", LIBAVCODEC_IDENT) ;
vorbis_comment_add_tag(&context->vc, "encoder", LIBAVCODEC_IDENT);

vorbis_analysis_headerout(&context->vd, &context->vc, &header,
&header_comm, &header_code);
&header_comm, &header_code);

avccontext->extradata_size=
avccontext->extradata_size =
1 + xiph_len(header.bytes) + xiph_len(header_comm.bytes) +
header_code.bytes;
p = avccontext->extradata =
av_malloc(avccontext->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
p[0] = 2;
offset = 1;
av_malloc(avccontext->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
p[0] = 2;
offset = 1;
offset += av_xiphlacing(&p[offset], header.bytes);
offset += av_xiphlacing(&p[offset], header_comm.bytes);
memcpy(&p[offset], header.packet, header.bytes);
Expand All @@ -169,60 +198,61 @@ static av_cold int oggvorbis_encode_init(AVCodecContext *avccontext) {
offset += header_code.bytes;
assert(offset == avccontext->extradata_size);

/* vorbis_block_clear(&context->vb);
#if 0
vorbis_block_clear(&context->vb);
vorbis_dsp_clear(&context->vd);
vorbis_info_clear(&context->vi);*/
vorbis_info_clear(&context->vi);
#endif
vorbis_comment_clear(&context->vc);

avccontext->frame_size = OGGVORBIS_FRAME_SIZE ;
avccontext->frame_size = OGGVORBIS_FRAME_SIZE;

avccontext->coded_frame= avcodec_alloc_frame();
avccontext->coded_frame->key_frame= 1;
avccontext->coded_frame = avcodec_alloc_frame();
avccontext->coded_frame->key_frame = 1;

return 0 ;
return 0;
}


static int oggvorbis_encode_frame(AVCodecContext *avccontext,
unsigned char *packets,
int buf_size, void *data)
int buf_size, void *data)
{
OggVorbisContext *context = avccontext->priv_data ;
ogg_packet op ;
signed short *audio = data ;
OggVorbisContext *context = avccontext->priv_data;
ogg_packet op;
signed short *audio = data;
int l;

if(data) {
if (data) {
const int samples = avccontext->frame_size;
float **buffer ;
float **buffer;
int c, channels = context->vi.channels;

buffer = vorbis_analysis_buffer(&context->vd, samples) ;
buffer = vorbis_analysis_buffer(&context->vd, samples);
for (c = 0; c < channels; c++) {
int co = (channels > 8) ? c :
ff_vorbis_encoding_channel_layout_offsets[channels-1][c];
for(l = 0 ; l < samples ; l++)
buffer[c][l]=audio[l*channels+co]/32768.f;
ff_vorbis_encoding_channel_layout_offsets[channels - 1][c];
for (l = 0; l < samples; l++)
buffer[c][l] = audio[l * channels + co] / 32768.f;
}
vorbis_analysis_wrote(&context->vd, samples) ;
vorbis_analysis_wrote(&context->vd, samples);
} else {
if(!context->eof)
vorbis_analysis_wrote(&context->vd, 0) ;
if (!context->eof)
vorbis_analysis_wrote(&context->vd, 0);
context->eof = 1;
}

while(vorbis_analysis_blockout(&context->vd, &context->vb) == 1) {
while (vorbis_analysis_blockout(&context->vd, &context->vb) == 1) {
vorbis_analysis(&context->vb, NULL);
vorbis_bitrate_addblock(&context->vb) ;
vorbis_bitrate_addblock(&context->vb);

while(vorbis_bitrate_flushpacket(&context->vd, &op)) {
while (vorbis_bitrate_flushpacket(&context->vd, &op)) {
/* i'd love to say the following line is a hack, but sadly it's
* not, apparently the end of stream decision is in libogg. */
if(op.bytes==1 && op.e_o_s)
if (op.bytes == 1 && op.e_o_s)
continue;
if (context->buffer_index + sizeof(ogg_packet) + op.bytes > BUFFER_SIZE) {
av_log(avccontext, AV_LOG_ERROR, "libvorbis: buffer overflow.");
return -1;
av_log(avccontext, AV_LOG_ERROR, "libvorbis: buffer overflow.\n");
return AVERROR(EINVAL);
}
memcpy(context->buffer + context->buffer_index, &op, sizeof(ogg_packet));
context->buffer_index += sizeof(ogg_packet);
Expand All @@ -232,18 +262,18 @@ static int oggvorbis_encode_frame(AVCodecContext *avccontext,
}
}

l=0;
if(context->buffer_index){
ogg_packet *op2= (ogg_packet*)context->buffer;
l = 0;
if (context->buffer_index) {
ogg_packet *op2 = (ogg_packet *)context->buffer;
op2->packet = context->buffer + sizeof(ogg_packet);

l= op2->bytes;
avccontext->coded_frame->pts= av_rescale_q(op2->granulepos, (AVRational){1, avccontext->sample_rate}, avccontext->time_base);
l = op2->bytes;
avccontext->coded_frame->pts = av_rescale_q(op2->granulepos, (AVRational) { 1, avccontext->sample_rate }, avccontext->time_base);
//FIXME we should reorder the user supplied pts and not assume that they are spaced by 1/sample_rate

if (l > buf_size) {
av_log(avccontext, AV_LOG_ERROR, "libvorbis: buffer overflow.");
return -1;
av_log(avccontext, AV_LOG_ERROR, "libvorbis: buffer overflow.\n");
return AVERROR(EINVAL);
}

memcpy(packets, op2->packet, l);
Expand All @@ -255,12 +285,12 @@ static int oggvorbis_encode_frame(AVCodecContext *avccontext,
return l;
}


static av_cold int oggvorbis_encode_close(AVCodecContext *avccontext) {
OggVorbisContext *context = avccontext->priv_data ;
static av_cold int oggvorbis_encode_close(AVCodecContext *avccontext)
{
OggVorbisContext *context = avccontext->priv_data;
/* ogg_packet op ; */

vorbis_analysis_wrote(&context->vd, 0) ; /* notify vorbisenc this is EOF */
vorbis_analysis_wrote(&context->vd, 0); /* notify vorbisenc this is EOF */

vorbis_block_clear(&context->vb);
vorbis_dsp_clear(&context->vd);
Expand All @@ -269,10 +299,9 @@ static av_cold int oggvorbis_encode_close(AVCodecContext *avccontext) {
av_freep(&avccontext->coded_frame);
av_freep(&avccontext->extradata);

return 0 ;
return 0;
}


AVCodec ff_libvorbis_encoder = {
.name = "libvorbis",
.type = AVMEDIA_TYPE_AUDIO,
Expand All @@ -282,7 +311,7 @@ AVCodec ff_libvorbis_encoder = {
.encode = oggvorbis_encode_frame,
.close = oggvorbis_encode_close,
.capabilities = CODEC_CAP_DELAY,
.sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE},
.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE },
.long_name = NULL_IF_CONFIG_SMALL("libvorbis Vorbis"),
.priv_class = &class,
};
2 changes: 1 addition & 1 deletion libavcodec/libx264.c
Original file line number Diff line number Diff line change
Expand Up @@ -696,7 +696,7 @@ AVCodec ff_libx264_encoder = {
.init = X264_init,
.encode = X264_frame,
.close = X264_close,
.capabilities = CODEC_CAP_DELAY,
.capabilities = CODEC_CAP_DELAY | CODEC_CAP_AUTO_THREADS,
.long_name = NULL_IF_CONFIG_SMALL("libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10"),
.priv_class = &class,
.defaults = x264_defaults,
Expand Down
108 changes: 89 additions & 19 deletions libavcodec/mjpegdec.c
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
return -1;
}

if(s->v_max==1 && s->h_max==1 && s->lossless==1) s->rgb=1;
if(s->v_max==1 && s->h_max==1 && s->lossless==1 && nb_components==3) s->rgb=1;

/* if different size, realloc/alloc picture */
/* XXX: also check h_count and v_count */
Expand Down Expand Up @@ -337,12 +337,22 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
}
assert(s->nb_components==3);
break;
case 0x12121100:
s->avctx->pix_fmt = s->cs_itu601 ? PIX_FMT_YUV444P : PIX_FMT_YUVJ444P;
s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG;
s->yuv442 = 1;
break;
case 0x11000000:
s->avctx->pix_fmt = PIX_FMT_GRAY8;
if(s->bits <= 8)
s->avctx->pix_fmt = PIX_FMT_GRAY8;
else
s->avctx->pix_fmt = PIX_FMT_GRAY16;
break;
case 0x12111100:
case 0x22211100:
s->avctx->pix_fmt = s->cs_itu601 ? PIX_FMT_YUV440P : PIX_FMT_YUVJ440P;
s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG;
s->yuv421 = pix_fmt_id == 0x22211100;
break;
case 0x21111100:
s->avctx->pix_fmt = s->cs_itu601 ? PIX_FMT_YUV422P : PIX_FMT_YUVJ422P;
Expand Down Expand Up @@ -642,7 +652,7 @@ static int decode_block_refinement(MJpegDecodeContext *s, DCTELEM *block, uint8_
#undef REFINE_BIT
#undef ZERO_RUN

static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, int predictor, int point_transform){
static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, int nb_components, int predictor, int point_transform){
int i, mb_x, mb_y;
uint16_t (*buffer)[4];
int left[3], top[3], topleft[3];
Expand All @@ -653,7 +663,7 @@ static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, int predictor, int point
buffer= s->ljpeg_buffer;

for(i=0; i<3; i++){
buffer[0][i]= 1 << (s->bits + point_transform - 1);
buffer[0][i]= 1 << (s->bits - 1);
}
for(mb_y = 0; mb_y < s->mb_height; mb_y++) {
const int modified_predictor= mb_y ? predictor : 1;
Expand All @@ -669,7 +679,7 @@ static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, int predictor, int point
if (s->restart_interval && !s->restart_count)
s->restart_count = s->restart_interval;

for(i=0;i<3;i++) {
for(i=0;i<nb_components;i++) {
int pred, dc;

topleft[i]= top[i];
Expand Down Expand Up @@ -704,10 +714,11 @@ static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, int predictor, int point
ptr[3*mb_x+2] = buffer[mb_x][2] + ptr[3*mb_x+1];
}
}else{
for(mb_x = 0; mb_x < s->mb_width; mb_x++) {
ptr[3*mb_x+0] = buffer[mb_x][2];
ptr[3*mb_x+1] = buffer[mb_x][1];
ptr[3*mb_x+2] = buffer[mb_x][0];
for(i=0;i<nb_components;i++) {
int c= s->comp_index[i];
for(mb_x = 0; mb_x < s->mb_width; mb_x++) {
ptr[3*mb_x+2-c] = buffer[mb_x][i];
}
}
}
}
Expand All @@ -716,7 +727,12 @@ static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, int predictor, int point

static int ljpeg_decode_yuv_scan(MJpegDecodeContext *s, int predictor, int point_transform){
int i, mb_x, mb_y;
const int nb_components=3;
const int nb_components=s->nb_components;
int bits= (s->bits+7)&~7;

point_transform += bits - s->bits;

av_assert0(nb_components==1 || nb_components==3);

for(mb_y = 0; mb_y < s->mb_height; mb_y++) {
for(mb_x = 0; mb_x < s->mb_width; mb_x++) {
Expand All @@ -726,6 +742,7 @@ static int ljpeg_decode_yuv_scan(MJpegDecodeContext *s, int predictor, int point
if(mb_x==0 || mb_y==0 || s->interlaced){
for(i=0;i<nb_components;i++) {
uint8_t *ptr;
uint16_t *ptr16;
int n, h, v, x, y, c, j, linesize;
n = s->nb_blocks[i];
c = s->comp_index[i];
Expand All @@ -735,13 +752,19 @@ static int ljpeg_decode_yuv_scan(MJpegDecodeContext *s, int predictor, int point
y = 0;
linesize= s->linesize[c];

if(bits>8) linesize /= 2;

for(j=0; j<n; j++) {
int pred, dc;

dc = mjpeg_decode_dc(s, s->dc_index[i]);
if(dc == 0xFFFF)
return -1;
if(bits<=8){
ptr = s->picture.data[c] + (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){
pred= 128 << point_transform;
pred= 1 << (bits - 1);
}else{
pred= ptr[-1];
}
Expand All @@ -755,11 +778,27 @@ static int ljpeg_decode_yuv_scan(MJpegDecodeContext *s, int predictor, int point

if (s->interlaced && s->bottom_field)
ptr += linesize >> 1;
dc = mjpeg_decode_dc(s, s->dc_index[i]);
if(dc == 0xFFFF)
return -1;
*ptr= pred + (dc << point_transform);
}else{
ptr16 = s->picture.data[c] + 2*(linesize * (v * mb_y + y)) + 2*(h * mb_x + x); //FIXME optimize this crap
if(y==0 && mb_y==0){
if(x==0 && mb_x==0){
pred= 1 << (bits - 1);
}else{
pred= ptr16[-1];
}
}else{
if(x==0 && mb_x==0){
pred= ptr16[-linesize];
}else{
PREDICT(pred, ptr16[-linesize-1], ptr16[-linesize], ptr16[-1], predictor);
}
}

if (s->interlaced && s->bottom_field)
ptr16 += linesize >> 1;
*ptr16= pred + (dc << point_transform);
}
if (++x == h) {
x = 0;
y++;
Expand All @@ -769,6 +808,7 @@ static int ljpeg_decode_yuv_scan(MJpegDecodeContext *s, int predictor, int point
}else{
for(i=0;i<nb_components;i++) {
uint8_t *ptr;
uint16_t *ptr16;
int n, h, v, x, y, c, j, linesize, dc;
n = s->nb_blocks[i];
c = s->comp_index[i];
Expand All @@ -778,16 +818,25 @@ static int ljpeg_decode_yuv_scan(MJpegDecodeContext *s, int predictor, int point
y = 0;
linesize= s->linesize[c];

if(bits>8) linesize /= 2;

for(j=0; j<n; j++) {
int pred;

ptr = s->picture.data[c] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap
PREDICT(pred, ptr[-linesize-1], ptr[-linesize], ptr[-1], predictor);

dc = mjpeg_decode_dc(s, s->dc_index[i]);
if(dc == 0xFFFF)
return -1;
if(bits<=8){
ptr = s->picture.data[c] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap
PREDICT(pred, ptr[-linesize-1], ptr[-linesize], ptr[-1], predictor);

*ptr= pred + (dc << point_transform);
}else{
ptr16 = s->picture.data[c] + 2*(linesize * (v * mb_y + y)) + 2*(h * mb_x + x); //FIXME optimize this crap
PREDICT(pred, ptr16[-linesize-1], ptr16[-linesize], ptr16[-1], predictor);

*ptr16= pred + (dc << point_transform);
}
if (++x == h) {
x = 0;
y++;
Expand Down Expand Up @@ -1024,7 +1073,7 @@ int ff_mjpeg_decode_sos(MJpegDecodeContext *s,
if (s->dc_index[i] < 0 || s->ac_index[i] < 0 ||
s->dc_index[i] >= 4 || s->ac_index[i] >= 4)
goto out_of_range;
if (!s->vlcs[0][s->dc_index[i]].table || !s->vlcs[1][s->ac_index[i]].table)
if (!s->vlcs[0][s->dc_index[i]].table || !(s->progressive ? s->vlcs[2][s->ac_index[0]].table : s->vlcs[1][s->ac_index[i]].table))
goto out_of_range;
}

Expand Down Expand Up @@ -1073,7 +1122,7 @@ int ff_mjpeg_decode_sos(MJpegDecodeContext *s,
return -1;
}else{
if(s->rgb){
if(ljpeg_decode_rgb_scan(s, predictor, point_transform) < 0)
if(ljpeg_decode_rgb_scan(s, nb_components, predictor, point_transform) < 0)
return -1;
}else{
if(ljpeg_decode_yuv_scan(s, predictor, point_transform) < 0)
Expand All @@ -1091,6 +1140,27 @@ int ff_mjpeg_decode_sos(MJpegDecodeContext *s,
return -1;
}
}
if (s->yuv421) {
uint8_t *line = s->picture_ptr->data[2];
for (i = 0; i < s->height / 2; i++) {
for (index = s->width - 1; index; index--)
line[index] = (line[index / 2] + line[(index + 1) / 2]) >> 1;
line += s->linesize[2];
}
} else if (s->yuv442) {
uint8_t *dst = &((uint8_t *)s->picture_ptr->data[2])[(s->height - 1) * s->linesize[2]];
for (i = s->height - 1; i; i--) {
uint8_t *src1 = &((uint8_t *)s->picture_ptr->data[2])[i / 2 * s->linesize[2]];
uint8_t *src2 = &((uint8_t *)s->picture_ptr->data[2])[(i + 1) / 2 * s->linesize[2]];
if (src1 == src2) {
memcpy(dst, src1, s->width);
} else {
for (index = 0; index < s->width; index++)
dst[index] = (src1[index] + src2[index]) >> 1;
}
dst -= s->linesize[2];
}
}
emms_c();
return 0;
out_of_range:
Expand Down
2 changes: 2 additions & 0 deletions libavcodec/mjpegdec.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ typedef struct MJpegDecodeContext {
int ls;
int progressive;
int rgb;
int yuv421;
int yuv442;
int rct; /* standard rct */
int pegasus_rct; /* pegasus reversible colorspace transform */
int bits; /* bits per component */
Expand Down
2 changes: 1 addition & 1 deletion libavcodec/mjpegenc.c
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,6 @@ AVCodec ff_amv_encoder = {
.init = MPV_encode_init,
.encode = amv_encode_picture,
.close = MPV_encode_end,
.pix_fmts= (enum PixelFormat[]){PIX_FMT_YUVJ420P, PIX_FMT_YUVJ422P, -1},
.pix_fmts= (enum PixelFormat[]){PIX_FMT_YUVJ420P, PIX_FMT_YUVJ422P, PIX_FMT_NONE},
.long_name = NULL_IF_CONFIG_SMALL("AMV Video"),
};
3 changes: 3 additions & 0 deletions libavcodec/mlp_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,9 @@ static int mlp_parse(AVCodecParserContext *s,
mp->bytes_left = ((mp->pc.index > 0 ? mp->pc.buffer[0] : buf[0]) << 8)
| (mp->pc.index > 1 ? mp->pc.buffer[1] : buf[1-mp->pc.index]);
mp->bytes_left = (mp->bytes_left & 0xfff) * 2;
if (mp->bytes_left <= 0) { // prevent infinite loop
goto lost_sync;
}
mp->bytes_left -= mp->pc.index;
}

Expand Down
4 changes: 3 additions & 1 deletion libavcodec/mpeg12.c
Original file line number Diff line number Diff line change
Expand Up @@ -2485,7 +2485,9 @@ static int decode_chunks(AVCodecContext *avctx,
}

if (HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_SLICE)) {
int threshold= (s2->mb_height*s->slice_count + avctx->thread_count/2) / avctx->thread_count;
int threshold = (s2->mb_height * s->slice_count +
s2->slice_context_count / 2) /
s2->slice_context_count;
av_assert0(avctx->thread_count > 1);
if (threshold <= mb_y) {
MpegEncContext *thread_context = s2->thread_context[s->slice_count];
Expand Down
3 changes: 2 additions & 1 deletion libavcodec/mpegaudiodec.c
Original file line number Diff line number Diff line change
Expand Up @@ -1427,6 +1427,7 @@ static int mp_decode_layer3(MPADecodeContext *s)
}

if (!s->adu_mode) {
int skip;
const uint8_t *ptr = s->gb.buffer + (get_bits_count(&s->gb)>>3);
assert((get_bits_count(&s->gb) & 7) == 0);
/* now we get bits from the main_data_begin offset */
Expand All @@ -1436,7 +1437,7 @@ static int mp_decode_layer3(MPADecodeContext *s)
memcpy(s->last_buf + s->last_buf_size, ptr, EXTRABYTES);
s->in_gb = s->gb;
init_get_bits(&s->gb, s->last_buf, s->last_buf_size*8);
#if CONFIG_SAFE_BITSTREAM_READER
#if !UNCHECKED_BITSTREAM_READER
s->gb.size_in_bits_plus8 += EXTRABYTES * 8;
#endif
skip_bits_long(&s->gb, 8*(s->last_buf_size - main_data_begin));
Expand Down
69 changes: 36 additions & 33 deletions libavcodec/mpegvideo.c
Original file line number Diff line number Diff line change
Expand Up @@ -638,6 +638,8 @@ void MPV_common_defaults(MpegEncContext *s)

s->picture_range_start = 0;
s->picture_range_end = MAX_PICTURE_COUNT;

s->slice_context_count = 1;
}

/**
Expand All @@ -656,11 +658,13 @@ void MPV_decode_defaults(MpegEncContext *s)
*/
av_cold int MPV_common_init(MpegEncContext *s)
{
int y_size, c_size, yc_size, i, mb_array_size, mv_table_size, x, y,
threads = (s->encoding ||
(HAVE_THREADS &&
s->avctx->active_thread_type & FF_THREAD_SLICE)) ?
s->avctx->thread_count : 1;
int y_size, c_size, yc_size, i, mb_array_size, mv_table_size, x, y;
int nb_slices = (HAVE_THREADS &&
s->avctx->active_thread_type & FF_THREAD_SLICE) ?
s->avctx->thread_count : 1;

if (s->encoding && s->avctx->slices)
nb_slices = s->avctx->slices;

if (s->codec_id == CODEC_ID_MPEG2VIDEO && !s->progressive_sequence)
s->mb_height = (s->height + 31) / 32 * 2;
Expand All @@ -673,14 +677,15 @@ av_cold int MPV_common_init(MpegEncContext *s)
return -1;
}

if ((s->encoding || (s->avctx->active_thread_type & FF_THREAD_SLICE)) &&
(s->avctx->thread_count > MAX_THREADS ||
(s->avctx->thread_count > s->mb_height && s->mb_height))) {
int max_threads = FFMIN(MAX_THREADS, s->mb_height);
av_log(s->avctx, AV_LOG_WARNING,
"too many threads (%d), reducing to %d\n",
s->avctx->thread_count, max_threads);
threads = max_threads;
if (nb_slices > MAX_THREADS || (nb_slices > s->mb_height && s->mb_height)) {
int max_slices;
if (s->mb_height)
max_slices = FFMIN(MAX_THREADS, s->mb_height);
else
max_slices = MAX_THREADS;
av_log(s->avctx, AV_LOG_WARNING, "too many threads/slices (%d),"
" reducing to %d\n", nb_slices, max_slices);
nb_slices = max_slices;
}

if ((s->width || s->height) &&
Expand Down Expand Up @@ -827,37 +832,33 @@ av_cold int MPV_common_init(MpegEncContext *s)
// Note the + 1 is for a quicker mpeg4 slice_end detection

s->parse_context.state = -1;
if ((s->avctx->debug & (FF_DEBUG_VIS_QP | FF_DEBUG_VIS_MB_TYPE)) ||
s->avctx->debug_mv) {
s->visualization_buffer[0] = av_malloc((s->mb_width * 16 +
2 * EDGE_WIDTH) * s->mb_height * 16 + 2 * EDGE_WIDTH);
s->visualization_buffer[1] = av_malloc((s->mb_width * 16 +
2 * EDGE_WIDTH) * s->mb_height * 16 + 2 * EDGE_WIDTH);
s->visualization_buffer[2] = av_malloc((s->mb_width * 16 +
2 * EDGE_WIDTH) * s->mb_height * 16 + 2 * EDGE_WIDTH);
}

s->context_initialized = 1;
s->thread_context[0] = s;

if (s->encoding || (HAVE_THREADS && s->avctx->active_thread_type&FF_THREAD_SLICE)) {
for (i = 1; i < threads; i++) {
// if (s->width && s->height) {
if (nb_slices > 1) {
for (i = 1; i < nb_slices; i++) {
s->thread_context[i] = av_malloc(sizeof(MpegEncContext));
memcpy(s->thread_context[i], s, sizeof(MpegEncContext));
}

for (i = 0; i < threads; i++) {
for (i = 0; i < nb_slices; i++) {
if (init_duplicate_context(s->thread_context[i], s) < 0)
goto fail;
s->thread_context[i]->start_mb_y = (s->mb_height*(i ) + s->avctx->thread_count / 2) / s->avctx->thread_count;
s->thread_context[i]->end_mb_y = (s->mb_height*(i+1) + s->avctx->thread_count / 2) / s->avctx->thread_count;
s->thread_context[i]->start_mb_y =
(s->mb_height * (i) + nb_slices / 2) / nb_slices;
s->thread_context[i]->end_mb_y =
(s->mb_height * (i + 1) + nb_slices / 2) / nb_slices;
}
} else {
if (init_duplicate_context(s, s) < 0)
goto fail;
s->start_mb_y = 0;
s->end_mb_y = s->mb_height;
}
s->slice_context_count = nb_slices;
// }

return 0;
fail:
Expand All @@ -870,13 +871,14 @@ void MPV_common_end(MpegEncContext *s)
{
int i, j, k;

if (s->encoding || (HAVE_THREADS && s->avctx->active_thread_type & FF_THREAD_SLICE)) {
for (i = 0; i < s->avctx->thread_count; i++) {
if (s->slice_context_count > 1) {
for (i = 0; i < s->slice_context_count; i++) {
free_duplicate_context(s->thread_context[i]);
}
for (i = 1; i < s->avctx->thread_count; i++) {
for (i = 1; i < s->slice_context_count; i++) {
av_freep(&s->thread_context[i]);
}
s->slice_context_count = 1;
} else free_duplicate_context(s);

av_freep(&s->parse_context.buffer);
Expand Down Expand Up @@ -1572,9 +1574,10 @@ void ff_print_debug_info(MpegEncContext *s, AVFrame *pict)
avcodec_get_chroma_sub_sample(s->avctx->pix_fmt,
&h_chroma_shift, &v_chroma_shift);
for (i = 0; i < 3; i++) {
memcpy(s->visualization_buffer[i], pict->data[i],
(i == 0) ? pict->linesize[i] * height:
pict->linesize[i] * height >> v_chroma_shift);
size_t size= (i == 0) ? pict->linesize[i] * height:
pict->linesize[i] * height >> v_chroma_shift;
s->visualization_buffer[i]= av_realloc(s->visualization_buffer[i], size);
memcpy(s->visualization_buffer[i], pict->data[i], size);
pict->data[i] = s->visualization_buffer[i];
}
pict->type = FF_BUFFER_TYPE_COPY;
Expand Down
1 change: 1 addition & 0 deletions libavcodec/mpegvideo.h
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ typedef struct MpegEncContext {
int start_mb_y; ///< start mb_y of this thread (so current thread should process start_mb_y <= row < end_mb_y)
int end_mb_y; ///< end mb_y of this thread (so current thread should process start_mb_y <= row < end_mb_y)
struct MpegEncContext *thread_context[MAX_THREADS];
int slice_context_count; ///< number of used thread_contexts

/**
* copy of the previous picture structure.
Expand Down
1,940 changes: 1,108 additions & 832 deletions libavcodec/mpegvideo_enc.c

Large diffs are not rendered by default.

16 changes: 8 additions & 8 deletions libavcodec/msvideo1enc.c
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ static int encode_frame(AVCodecContext *avctx, uint8_t *buf, int buf_size, void
c->keyint = 0;
else
c->keyint++;
p->pict_type= keyframe ? FF_I_TYPE : FF_P_TYPE;
p->pict_type= keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
p->key_frame= keyframe;

return dst - buf;
Expand Down Expand Up @@ -290,13 +290,13 @@ static av_cold int encode_end(AVCodecContext *avctx)
}

AVCodec ff_msvideo1_encoder = {
"msvideo1",
AVMEDIA_TYPE_VIDEO,
CODEC_ID_MSVIDEO1,
sizeof(Msvideo1EncContext),
encode_init,
encode_frame,
encode_end,
.name = "msvideo1",
.type = AVMEDIA_TYPE_VIDEO,
.id = CODEC_ID_MSVIDEO1,
.priv_data_size = sizeof(Msvideo1EncContext),
.init = encode_init,
.encode = encode_frame,
.close = encode_end,
.pix_fmts = (const enum PixelFormat[]){PIX_FMT_RGB555, PIX_FMT_NONE},
.long_name = NULL_IF_CONFIG_SMALL("Microsoft Video-1"),
};
2 changes: 1 addition & 1 deletion libavcodec/nellymoserdec.c
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ static int decode_tag(AVCodecContext *avctx, void *data,
samples_flt = (float *)s->frame.data[0];

for (i=0 ; i<blocks ; i++) {
if (avctx->sample_fmt == SAMPLE_FMT_FLT) {
if (avctx->sample_fmt == AV_SAMPLE_FMT_FLT) {
nelly_decode_block(s, buf, samples_flt);
samples_flt += NELLY_SAMPLES;
} else {
Expand Down
4 changes: 2 additions & 2 deletions libavcodec/options.c
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ static const AVOption options[]={
{"float", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_AA_FLOAT }, INT_MIN, INT_MAX, V|D, "aa"},
#endif
{"qns", "quantizer noise shaping", OFFSET(quantizer_noise_shaping), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E},
{"threads", NULL, OFFSET(thread_count), AV_OPT_TYPE_INT, {.dbl = 1 }, 0, INT_MAX, V|E|D, "threads"},
{"threads", NULL, OFFSET(thread_count), AV_OPT_TYPE_INT, {.dbl = 0 }, 0, INT_MAX, V|E|D, "threads"},
{"auto", "detect a good number of threads", 0, AV_OPT_TYPE_CONST, {.dbl = 0 }, INT_MIN, INT_MAX, V|E|D, "threads"},
{"me_threshold", "motion estimaton threshold", OFFSET(me_threshold), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E},
{"mb_threshold", "macroblock threshold", OFFSET(mb_threshold), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E},
Expand Down Expand Up @@ -507,7 +507,7 @@ static const AVOption options[]={
{"cholesky", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = AV_LPC_TYPE_CHOLESKY }, INT_MIN, INT_MAX, A|E, "lpc_type"},
{"lpc_passes", "deprecated, use flac-specific options", OFFSET(lpc_passes), AV_OPT_TYPE_INT, {.dbl = -1 }, INT_MIN, INT_MAX, A|E},
#endif
{"slices", "number of slices, used in parallelized decoding", OFFSET(slices), AV_OPT_TYPE_INT, {.dbl = 0 }, 0, INT_MAX, V|E},
{"slices", "number of slices, used in parallelized encoding", OFFSET(slices), AV_OPT_TYPE_INT, {.dbl = 0 }, 0, INT_MAX, V|E},
{"thread_type", "select multithreading type", OFFSET(thread_type), AV_OPT_TYPE_FLAGS, {.dbl = FF_THREAD_SLICE|FF_THREAD_FRAME }, 0, INT_MAX, V|E|D, "thread_type"},
{"slice", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_THREAD_SLICE }, INT_MIN, INT_MAX, V|E|D, "thread_type"},
{"frame", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_THREAD_FRAME }, INT_MIN, INT_MAX, V|E|D, "thread_type"},
Expand Down
19 changes: 16 additions & 3 deletions libavcodec/pamenc.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ static int pam_encode_frame(AVCodecContext *avctx, unsigned char *outbuf,
h = avctx->height;
w = avctx->width;
switch (avctx->pix_fmt) {
case PIX_FMT_MONOWHITE:
case PIX_FMT_MONOBLACK:
n = (w + 7) >> 3;
depth = 1;
maxval = 1;
Expand All @@ -62,6 +62,12 @@ static int pam_encode_frame(AVCodecContext *avctx, unsigned char *outbuf,
maxval = 255;
tuple_type = "GRAYSCALE";
break;
case PIX_FMT_GRAY8A:
n = w * 2;
depth = 2;
maxval = 255;
tuple_type = "GRAYSCALE_ALPHA";
break;
case PIX_FMT_RGB24:
n = w * 3;
depth = 3;
Expand All @@ -78,7 +84,7 @@ static int pam_encode_frame(AVCodecContext *avctx, unsigned char *outbuf,
return -1;
}
snprintf(s->bytestream, s->bytestream_end - s->bytestream,
"P7\nWIDTH %d\nHEIGHT %d\nDEPTH %d\nMAXVAL %d\nTUPLETYPE %s\nENDHDR\n",
"P7\nWIDTH %d\nHEIGHT %d\nDEPTH %d\nMAXVAL %d\nTUPLTYPE %s\nENDHDR\n",
w, h, depth, maxval, tuple_type);
s->bytestream += strlen(s->bytestream);

Expand All @@ -97,6 +103,13 @@ static int pam_encode_frame(AVCodecContext *avctx, unsigned char *outbuf,
}
ptr += linesize;
}
} else if (avctx->pix_fmt == PIX_FMT_MONOBLACK){
int j;
for (i = 0; i < h; i++) {
for (j = 0; j < w; j++)
*s->bytestream++ = ptr[j >> 3] >> (7 - j & 7) & 1;
ptr += linesize;
}
} else {
for (i = 0; i < h; i++) {
memcpy(s->bytestream, ptr, n);
Expand All @@ -115,6 +128,6 @@ AVCodec ff_pam_encoder = {
.priv_data_size = sizeof(PNMContext),
.init = ff_pnm_init,
.encode = pam_encode_frame,
.pix_fmts = (const enum PixelFormat[]){PIX_FMT_RGB24, PIX_FMT_RGB32, PIX_FMT_GRAY8, PIX_FMT_MONOWHITE, PIX_FMT_NONE},
.pix_fmts = (const enum PixelFormat[]){PIX_FMT_RGB24, PIX_FMT_RGB32, PIX_FMT_GRAY8, PIX_FMT_GRAY8A, PIX_FMT_MONOBLACK, PIX_FMT_NONE},
.long_name = NULL_IF_CONFIG_SMALL("PAM (Portable AnyMap) image"),
};
7 changes: 7 additions & 0 deletions libavcodec/pcxenc.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

#include "avcodec.h"
#include "bytestream.h"
#include "libavutil/imgutils.h"

typedef struct PCXContext {
AVFrame picture;
Expand Down Expand Up @@ -105,6 +106,7 @@ static int pcx_encode_frame(AVCodecContext *avctx,

int bpp, nplanes, i, y, line_bytes, written;
const uint32_t *pal = NULL;
uint32_t palette256[256];
const uint8_t *src;

*pict = *(AVFrame *)data;
Expand All @@ -126,6 +128,11 @@ static int pcx_encode_frame(AVCodecContext *avctx,
case PIX_FMT_RGB4_BYTE:
case PIX_FMT_BGR4_BYTE:
case PIX_FMT_GRAY8:
bpp = 8;
nplanes = 1;
ff_set_systematic_pal2(palette256, avctx->pix_fmt);
pal = palette256;
break;
case PIX_FMT_PAL8:
bpp = 8;
nplanes = 1;
Expand Down
2 changes: 1 addition & 1 deletion libavcodec/pictordec.c
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ AVCodec ff_pictor_decoder = {
.type = AVMEDIA_TYPE_VIDEO,
.id = CODEC_ID_PICTOR,
.priv_data_size = sizeof(PicContext),
decode_init,
.init = decode_init,
.close = decode_end,
.decode = decode_frame,
.capabilities = CODEC_CAP_DR1,
Expand Down
21 changes: 19 additions & 2 deletions libavcodec/pngdec.c
Original file line number Diff line number Diff line change
Expand Up @@ -494,10 +494,10 @@ static int decode_frame(AVCodecContext *avctx,
} else if (s->bit_depth == 16 &&
s->color_type == PNG_COLOR_TYPE_RGB) {
avctx->pix_fmt = PIX_FMT_RGB48BE;
} else if (s->bit_depth == 1) {
avctx->pix_fmt = PIX_FMT_MONOBLACK;
} else if (s->color_type == PNG_COLOR_TYPE_PALETTE) {
avctx->pix_fmt = PIX_FMT_PAL8;
} else if (s->bit_depth == 1) {
avctx->pix_fmt = PIX_FMT_MONOBLACK;
} else if (s->bit_depth == 8 &&
s->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
avctx->pix_fmt = PIX_FMT_GRAY8A;
Expand Down Expand Up @@ -609,6 +609,23 @@ static int decode_frame(AVCodecContext *avctx,
}
exit_loop:

if(s->bits_per_pixel == 1 && s->color_type == PNG_COLOR_TYPE_PALETTE){
int i, j;
uint8_t *pd = s->current_picture->data[0];
for(j=0; j < s->height; j++) {
for(i=s->width/8-1; i>=0; i--) {
pd[8*i+7]= pd[i] &1;
pd[8*i+6]= (pd[i]>>1)&1;
pd[8*i+5]= (pd[i]>>2)&1;
pd[8*i+4]= (pd[i]>>3)&1;
pd[8*i+3]= (pd[i]>>4)&1;
pd[8*i+2]= (pd[i]>>5)&1;
pd[8*i+1]= (pd[i]>>6)&1;
pd[8*i+0]= pd[i]>>7;
}
pd += s->image_linesize;
}
}
if(s->bits_per_pixel == 2){
int i, j;
uint8_t *pd = s->current_picture->data[0];
Expand Down
5 changes: 4 additions & 1 deletion libavcodec/pnm.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,9 @@ int ff_pnm_decode_header(AVCodecContext *avctx, PNMContext * const s)
} else if (!strcmp(buf1, "MAXVAL")) {
pnm_get(s, buf1, sizeof(buf1));
maxval = strtol(buf1, NULL, 10);
} else if (!strcmp(buf1, "TUPLETYPE")) {
} else if (!strcmp(buf1, "TUPLTYPE") ||
// FFmpeg used to write invalid files
!strcmp(buf1, "TUPLETYPE")) {
pnm_get(s, tuple_type, sizeof(tuple_type));
} else if (!strcmp(buf1, "ENDHDR")) {
break;
Expand All @@ -107,6 +109,7 @@ int ff_pnm_decode_header(AVCodecContext *avctx, PNMContext * const s)

avctx->width = w;
avctx->height = h;
s->maxval = maxval;
if (depth == 1) {
if (maxval == 1)
avctx->pix_fmt = PIX_FMT_MONOWHITE;
Expand Down
2 changes: 1 addition & 1 deletion libavcodec/proresdec2.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
ff_proresdsp_init(&ctx->prodsp, avctx);

avctx->coded_frame = &ctx->frame;
ctx->frame.type = FF_I_TYPE;
ctx->frame.type = AV_PICTURE_TYPE_I;
ctx->frame.key_frame = 1;

ff_init_scantable_permutation(idct_permutation,
Expand Down
1 change: 0 additions & 1 deletion libavcodec/proresenc.c
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,5 @@ AVCodec ff_prores_encoder = {
.encode = prores_encode_frame,
.pix_fmts = (const enum PixelFormat[]){PIX_FMT_YUV422P10, PIX_FMT_NONE},
.long_name = NULL_IF_CONFIG_SMALL("Apple ProRes"),
.capabilities = 0,
.profiles = profiles
};
48 changes: 37 additions & 11 deletions libavcodec/pthread.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,21 @@
#if HAVE_SCHED_GETAFFINITY
#define _GNU_SOURCE
#include <sched.h>
#elif HAVE_GETSYSTEMINFO
#endif
#if HAVE_GETPROCESSAFFINITYMASK
#include <windows.h>
#elif HAVE_SYSCTL
#endif
#if HAVE_SYSCTL
#if HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
#include <sys/types.h>
#include <sys/param.h>
#include <sys/sysctl.h>
#endif
#if HAVE_SYSCONF
#include <unistd.h>
#endif

#include "avcodec.h"
#include "internal.h"
Expand Down Expand Up @@ -164,20 +172,29 @@ static int get_logical_cpus(AVCodecContext *avctx)
if (!ret) {
nb_cpus = CPU_COUNT(&cpuset);
}
#elif HAVE_GETSYSTEMINFO
SYSTEM_INFO sysinfo;
GetSystemInfo(&sysinfo);
nb_cpus = sysinfo.dwNumberOfProcessors;
#elif HAVE_GETPROCESSAFFINITYMASK
DWORD_PTR proc_aff, sys_aff;
ret = GetProcessAffinityMask(GetCurrentProcess(), &proc_aff, &sys_aff);
if (ret)
nb_cpus = av_popcount64(proc_aff);
#elif HAVE_SYSCTL && defined(HW_NCPU)
int mib[2] = { CTL_HW, HW_NCPU };
size_t len = sizeof(nb_cpus);

ret = sysctl(mib, 2, &nb_cpus, &len, NULL, 0);
if (ret == -1)
nb_cpus = 0;
#elif HAVE_SYSCONF && defined(_SC_NPROC_ONLN)
nb_cpus = sysconf(_SC_NPROC_ONLN);
#elif HAVE_SYSCONF && defined(_SC_NPROCESSORS_ONLN)
nb_cpus = sysconf(_SC_NPROCESSORS_ONLN);
#endif
av_log(avctx, AV_LOG_DEBUG, "detected %d logical cores\n", nb_cpus);
return FFMIN(nb_cpus, MAX_AUTO_THREADS);

if (avctx->height)
nb_cpus = FFMIN(nb_cpus, (avctx->height+15)/16);

return nb_cpus;
}


Expand Down Expand Up @@ -287,9 +304,11 @@ static int thread_init(AVCodecContext *avctx)

if (!thread_count) {
int nb_cpus = get_logical_cpus(avctx);
// use number of cores + 1 as thread count if there is motre than one
// use number of cores + 1 as thread count if there is more than one
if (nb_cpus > 1)
thread_count = avctx->thread_count = nb_cpus + 1;
thread_count = avctx->thread_count = FFMIN(nb_cpus + 1, MAX_AUTO_THREADS);
else
thread_count = avctx->thread_count = 1;
}

if (thread_count <= 1) {
Expand Down Expand Up @@ -765,9 +784,13 @@ static int frame_thread_init(AVCodecContext *avctx)

if (!thread_count) {
int nb_cpus = get_logical_cpus(avctx);
// use number of cores + 1 as thread count if there is motre than one
if ((avctx->debug & (FF_DEBUG_VIS_QP | FF_DEBUG_VIS_MB_TYPE)) || avctx->debug_mv)
nb_cpus = 1;
// use number of cores + 1 as thread count if there is more than one
if (nb_cpus > 1)
thread_count = avctx->thread_count = nb_cpus + 1;
thread_count = avctx->thread_count = FFMIN(nb_cpus + 1, MAX_AUTO_THREADS);
else
thread_count = avctx->thread_count = 1;
}

if (thread_count <= 1) {
Expand Down Expand Up @@ -984,6 +1007,9 @@ static void validate_thread_parameters(AVCodecContext *avctx)
} else if (avctx->codec->capabilities & CODEC_CAP_SLICE_THREADS &&
avctx->thread_type & FF_THREAD_SLICE) {
avctx->active_thread_type = FF_THREAD_SLICE;
} else if (!(avctx->codec->capabilities & CODEC_CAP_AUTO_THREADS)) {
avctx->thread_count = 1;
avctx->active_thread_type = 0;
}
}

Expand Down
12 changes: 9 additions & 3 deletions libavcodec/qpeg.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ typedef struct QpegContext{
uint32_t pal[256];
} QpegContext;

static void qpeg_decode_intra(const uint8_t *src, uint8_t *dst, int size,
static int qpeg_decode_intra(const uint8_t *src, uint8_t *dst, int size,
int stride, int width, int height)
{
int i;
Expand Down Expand Up @@ -94,6 +94,8 @@ static void qpeg_decode_intra(const uint8_t *src, uint8_t *dst, int size,
}
} else {
size -= copy;
if (size<0)
return AVERROR_INVALIDDATA;
for(i = 0; i < copy; i++) {
dst[filled++] = *src++;
if (filled >= width) {
Expand All @@ -106,6 +108,7 @@ static void qpeg_decode_intra(const uint8_t *src, uint8_t *dst, int size,
}
}
}
return 0;
}

static const int qpeg_table_h[16] =
Expand Down Expand Up @@ -259,7 +262,7 @@ static int decode_frame(AVCodecContext *avctx,
AVFrame * p= (AVFrame*)&a->pic;
AVFrame * ref= (AVFrame*)&a->ref;
uint8_t* outdata;
int delta;
int delta, ret = 0;
const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL);

if(ref->data[0])
Expand All @@ -273,12 +276,15 @@ static int decode_frame(AVCodecContext *avctx,
}
outdata = a->pic.data[0];
if(buf[0x85] == 0x10) {
qpeg_decode_intra(buf+0x86, outdata, buf_size - 0x86, a->pic.linesize[0], avctx->width, avctx->height);
ret = qpeg_decode_intra(buf+0x86, outdata, buf_size - 0x86, a->pic.linesize[0], avctx->width, avctx->height);
} else {
delta = buf[0x85];
qpeg_decode_inter(buf+0x86, outdata, buf_size - 0x86, a->pic.linesize[0], avctx->width, avctx->height, delta, buf + 4, a->ref.data[0]);
}

if (ret<0)
return ret;

/* make the palette available on the way out */
if (pal) {
a->pic.palette_has_changed = 1;
Expand Down
19 changes: 18 additions & 1 deletion libavcodec/r210dec.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,13 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
for (h = 0; h < avctx->height; h++) {
uint16_t *dst = (uint16_t *)dst_line;
for (w = 0; w < avctx->width; w++) {
uint32_t pixel = av_be2ne32(*src++);
uint32_t pixel;
uint16_t r, g, b;
if (avctx->codec_id==CODEC_ID_AVRP) {
pixel = av_le2ne32(*src++);
} else {
pixel = av_be2ne32(*src++);
}
if (avctx->codec_id==CODEC_ID_R210) {
b = pixel << 6;
g = (pixel >> 4) & 0xffc0;
Expand Down Expand Up @@ -120,3 +125,15 @@ AVCodec ff_r10k_decoder = {
.long_name = NULL_IF_CONFIG_SMALL("AJA Kona 10-bit RGB Codec"),
};
#endif
#if CONFIG_AVRP_DECODER
AVCodec ff_avrp_decoder = {
.name = "avrp",
.type = AVMEDIA_TYPE_VIDEO,
.id = CODEC_ID_AVRP,
.init = decode_init,
.close = decode_close,
.decode = decode_frame,
.capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Avid 1:1 10-bit RGB Packer"),
};
#endif
2 changes: 1 addition & 1 deletion libavcodec/ra144enc.c
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ static int adaptive_cb_search(const int16_t *adapt_cb, float *work,
ff_celp_lp_synthesis_filterf(work, coefs, exc, BLOCKSIZE, LPC_ORDER);
for (i = 0; i < BLOCKSIZE; i++)
data[i] -= best_gain * work[i];
return (best_vect - BLOCKSIZE / 2 + 1);
return best_vect - BLOCKSIZE / 2 + 1;
}


Expand Down
85 changes: 47 additions & 38 deletions libavcodec/rv34.c
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ static int rv34_decode_cbp(GetBitContext *gb, RV34VLC *vlc, int table)
/**
* Get one coefficient value from the bistream and store it.
*/
static inline void decode_coeff(DCTELEM *dst, int coef, int esc, GetBitContext *gb, VLC* vlc)
static inline void decode_coeff(DCTELEM *dst, int coef, int esc, GetBitContext *gb, VLC* vlc, int q)
{
if(coef){
if(coef == esc){
Expand All @@ -225,30 +225,50 @@ static inline void decode_coeff(DCTELEM *dst, int coef, int esc, GetBitContext *
}
if(get_bits1(gb))
coef = -coef;
*dst = coef;
*dst = (coef*q + 8) >> 4;
}
}

/**
* Decode 2x2 subblock of coefficients.
*/
static inline void decode_subblock(DCTELEM *dst, int code, const int is_block2, GetBitContext *gb, VLC *vlc)
static inline void decode_subblock(DCTELEM *dst, int code, const int is_block2, GetBitContext *gb, VLC *vlc, int q)
{
int coeffs[4];

coeffs[0] = modulo_three_table[code][0];
coeffs[1] = modulo_three_table[code][1];
coeffs[2] = modulo_three_table[code][2];
coeffs[3] = modulo_three_table[code][3];
decode_coeff(dst , coeffs[0], 3, gb, vlc);
decode_coeff(dst , coeffs[0], 3, gb, vlc, q);
if(is_block2){
decode_coeff(dst+8, coeffs[1], 2, gb, vlc);
decode_coeff(dst+1, coeffs[2], 2, gb, vlc);
decode_coeff(dst+8, coeffs[1], 2, gb, vlc, q);
decode_coeff(dst+1, coeffs[2], 2, gb, vlc, q);
}else{
decode_coeff(dst+1, coeffs[1], 2, gb, vlc);
decode_coeff(dst+8, coeffs[2], 2, gb, vlc);
decode_coeff(dst+1, coeffs[1], 2, gb, vlc, q);
decode_coeff(dst+8, coeffs[2], 2, gb, vlc, q);
}
decode_coeff(dst+9, coeffs[3], 2, gb, vlc);
decode_coeff(dst+9, coeffs[3], 2, gb, vlc, q);
}

static inline void decode_subblock3(DCTELEM *dst, int code, const int is_block2, GetBitContext *gb, VLC *vlc,
int q_dc, int q_ac1, int q_ac2)
{
int coeffs[4];

coeffs[0] = modulo_three_table[code][0];
coeffs[1] = modulo_three_table[code][1];
coeffs[2] = modulo_three_table[code][2];
coeffs[3] = modulo_three_table[code][3];
decode_coeff(dst , coeffs[0], 3, gb, vlc, q_dc);
if(is_block2){
decode_coeff(dst+8, coeffs[1], 2, gb, vlc, q_ac1);
decode_coeff(dst+1, coeffs[2], 2, gb, vlc, q_ac1);
}else{
decode_coeff(dst+1, coeffs[1], 2, gb, vlc, q_ac1);
decode_coeff(dst+8, coeffs[2], 2, gb, vlc, q_ac1);
}
decode_coeff(dst+9, coeffs[3], 2, gb, vlc, q_ac2);
}

/**
Expand All @@ -262,7 +282,7 @@ static inline void decode_subblock(DCTELEM *dst, int code, const int is_block2,
* o--o
*/

static inline void rv34_decode_block(DCTELEM *dst, GetBitContext *gb, RV34VLC *rvlc, int fc, int sc)
static inline void rv34_decode_block(DCTELEM *dst, GetBitContext *gb, RV34VLC *rvlc, int fc, int sc, int q_dc, int q_ac1, int q_ac2)
{
int code, pattern;

Expand All @@ -271,39 +291,23 @@ static inline void rv34_decode_block(DCTELEM *dst, GetBitContext *gb, RV34VLC *r
pattern = code & 0x7;

code >>= 3;
decode_subblock(dst, code, 0, gb, &rvlc->coefficient);
decode_subblock3(dst, code, 0, gb, &rvlc->coefficient, q_dc, q_ac1, q_ac2);

if(pattern & 4){
code = get_vlc2(gb, rvlc->second_pattern[sc].table, 9, 2);
decode_subblock(dst + 2, code, 0, gb, &rvlc->coefficient);
decode_subblock(dst + 2, code, 0, gb, &rvlc->coefficient, q_ac2);
}
if(pattern & 2){ // Looks like coefficients 1 and 2 are swapped for this block
code = get_vlc2(gb, rvlc->second_pattern[sc].table, 9, 2);
decode_subblock(dst + 8*2, code, 1, gb, &rvlc->coefficient);
decode_subblock(dst + 8*2, code, 1, gb, &rvlc->coefficient, q_ac2);
}
if(pattern & 1){
code = get_vlc2(gb, rvlc->third_pattern[sc].table, 9, 2);
decode_subblock(dst + 8*2+2, code, 0, gb, &rvlc->coefficient);
decode_subblock(dst + 8*2+2, code, 0, gb, &rvlc->coefficient, q_ac2);
}

}

/**
* Dequantize 4x4 block of DC values for 16x16 macroblock.
* @todo optimize
*/
static inline void rv34_dequant4x4_16x16(DCTELEM *block, int Qdc, int Q)
{
int i;

for(i = 0; i < 3; i++)
block[rv34_dezigzag[i]] = (block[rv34_dezigzag[i]] * Qdc + 8) >> 4;
for(; i < 16; i++)
block[rv34_dezigzag[i]] = (block[rv34_dezigzag[i]] * Q + 8) >> 4;
}
/** @} */ //block functions


/**
* @name RV30/40 bitstream parsing
* @{
Expand Down Expand Up @@ -676,8 +680,9 @@ static inline void rv34_mc(RV34DecContext *r, const int block_type,
srcY += src_y * s->linesize + src_x;
srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
if( (unsigned)(src_x - !!lx*2) > s->h_edge_pos - !!lx*2 - (width <<3) - 4
|| (unsigned)(src_y - !!ly*2) > s->v_edge_pos - !!ly*2 - (height<<3) - 4){
if(s->h_edge_pos - (width << 3) < 6 || s->v_edge_pos - (height << 3) < 6 ||
(unsigned)(src_x - !!lx*2) > s->h_edge_pos - !!lx*2 - (width <<3) - 4 ||
(unsigned)(src_y - !!ly*2) > s->v_edge_pos - !!ly*2 - (height<<3) - 4) {
uint8_t *uvbuf = s->edge_emu_buffer + 22 * s->linesize;

srcY -= 2 + 2*s->linesize;
Expand Down Expand Up @@ -1097,6 +1102,7 @@ static int rv34_decode_macroblock(RV34DecContext *r, int8_t *intra_types)
MpegEncContext *s = &r->s;
GetBitContext *gb = &s->gb;
int cbp, cbp2;
int q_dc, q_ac;
int i, blknum, blkoff;
LOCAL_ALIGNED_16(DCTELEM, block16, [64]);
int luma_dc_quant;
Expand Down Expand Up @@ -1133,31 +1139,34 @@ static int rv34_decode_macroblock(RV34DecContext *r, int8_t *intra_types)

luma_dc_quant = r->block_type == RV34_MB_P_MIX16x16 ? r->luma_dc_quant_p[s->qscale] : r->luma_dc_quant_i[s->qscale];
if(r->is16){
q_dc = rv34_qscale_tab[luma_dc_quant];
q_ac = rv34_qscale_tab[s->qscale];
memset(block16, 0, 64 * sizeof(*block16));
rv34_decode_block(block16, gb, r->cur_vlcs, 3, 0);
rv34_dequant4x4_16x16(block16, rv34_qscale_tab[luma_dc_quant],rv34_qscale_tab[s->qscale]);
rv34_decode_block(block16, gb, r->cur_vlcs, 3, 0, q_dc, q_dc, q_ac);
r->rdsp.rv34_inv_transform_tab[1](block16);
}

q_ac = rv34_qscale_tab[s->qscale];
for(i = 0; i < 16; i++, cbp >>= 1){
if(!r->is16 && !(cbp & 1)) continue;
blknum = ((i & 2) >> 1) + ((i & 8) >> 2);
blkoff = ((i & 1) << 2) + ((i & 4) << 3);
if(cbp & 1)
rv34_decode_block(s->block[blknum] + blkoff, gb, r->cur_vlcs, r->luma_vlc, 0);
r->rdsp.rv34_dequant4x4(s->block[blknum] + blkoff, rv34_qscale_tab[s->qscale],rv34_qscale_tab[s->qscale]);
rv34_decode_block(s->block[blknum] + blkoff, gb,
r->cur_vlcs, r->luma_vlc, 0, q_ac, q_ac, q_ac);
if(r->is16) //FIXME: optimize
s->block[blknum][blkoff] = block16[(i & 3) | ((i & 0xC) << 1)];
r->rdsp.rv34_inv_transform_tab[0](s->block[blknum] + blkoff);
}
if(r->block_type == RV34_MB_P_MIX16x16)
r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 1);
q_dc = rv34_qscale_tab[rv34_chroma_quant[1][s->qscale]];
q_ac = rv34_qscale_tab[rv34_chroma_quant[0][s->qscale]];
for(; i < 24; i++, cbp >>= 1){
if(!(cbp & 1)) continue;
blknum = ((i & 4) >> 2) + 4;
blkoff = ((i & 1) << 2) + ((i & 2) << 4);
rv34_decode_block(s->block[blknum] + blkoff, gb, r->cur_vlcs, r->chroma_vlc, 1);
r->rdsp.rv34_dequant4x4(s->block[blknum] + blkoff, rv34_qscale_tab[rv34_chroma_quant[1][s->qscale]],rv34_qscale_tab[rv34_chroma_quant[0][s->qscale]]);
rv34_decode_block(s->block[blknum] + blkoff, gb, r->cur_vlcs, r->chroma_vlc, 1, q_dc, q_ac, q_ac);
r->rdsp.rv34_inv_transform_tab[0](s->block[blknum] + blkoff);
}
if (IS_INTRA(s->current_picture_ptr->f.mb_type[mb_pos]))
Expand Down
10 changes: 0 additions & 10 deletions libavcodec/rv34data.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,16 +100,6 @@ static const uint16_t rv34_qscale_tab[32] = {
963, 1074, 1212, 1392, 1566, 1708, 1978, 2211
};

/**
* 4x4 dezigzag pattern
*/
static const uint8_t rv34_dezigzag[16] = {
0, 1, 8, 16,
9, 2, 3, 10,
17, 24, 25, 18,
11, 19, 26, 27
};

/**
* tables used to translate a quantizer value into a VLC set for decoding
* The first table is used for intraframes.
Expand Down
Loading