*
* Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
*
- * This file is part of FFmpeg.
+ * This file is part of Libav.
*
- * FFmpeg is free software; you can redistribute it and/or
+ * 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.
*
- * FFmpeg is distributed in the hope that it will be useful,
+ * 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 FFmpeg; if not, write to the Free Software
+ * License along with Libav; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#define MAX_QUANT_TABLES 8
#define MAX_CONTEXT_INPUTS 5
-extern const uint8_t ff_log2_run[32];
-
-static const int8_t quant3[256]={
- 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
--1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
--1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
--1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
--1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
--1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
--1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
--1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
--1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 0,
-};
+extern const uint8_t ff_log2_run[41];
static const int8_t quant5_10bit[256]={
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,
-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-1,-1,-1,
};
-static const int8_t quant7[256]={
- 0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
--3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,
--3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,
--3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,
--3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,
--3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,
--3,-3,-3,-3,-3,-3,-3,-3,-3,-2,-2,-2,-2,-2,-2,-2,
--2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,
--2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-1,-1,
-};
-static const int8_t quant9[256]={
- 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
--4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,
--4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,
--4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,
--4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,
--4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,
--4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,
--4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-3,-3,-3,-3,
--3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-2,-2,-2,-2,-1,-1,
-};
+
static const int8_t quant9_10bit[256]={
0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3,
-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,
-4,-4,-4,-4,-4,-3,-3,-3,-3,-3,-3,-3,-2,-2,-2,-1,
};
-static const int8_t quant13[256]={
- 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
--6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,
--6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,
--6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,
--6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,
--6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-6,-5,
--5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,
--5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,
--4,-4,-4,-4,-4,-4,-4,-4,-4,-3,-3,-3,-3,-2,-2,-1,
-};
static const uint8_t ver2_state[256]= {
0, 10, 10, 10, 10, 16, 16, 16, 28, 16, 16, 29, 42, 49, 20, 49,
uint8_t (*initial_states[MAX_QUANT_TABLES])[32];
int run_index;
int colorspace;
- int_fast16_t *sample_buffer;
+ int16_t *sample_buffer;
int gob_count;
int quant_table_count;
return diff;
}
-static inline int predict(int_fast16_t *src, int_fast16_t *last){
+static inline int predict(int16_t *src, int16_t *last)
+{
const int LT= last[-1];
const int T= last[ 0];
const int L = src[-1];
return mid_pred(L, L + T - LT, T);
}
-static inline int get_context(PlaneContext *p, int_fast16_t *src, int_fast16_t *last, int_fast16_t *last2){
+static inline int get_context(PlaneContext *p, int16_t *src,
+ int16_t *last, int16_t *last2)
+{
const int LT= last[-1];
const int T= last[ 0];
const int RT= last[ 1];
#undef put_rac
}
-static void av_noinline put_symbol(RangeCoder *c, uint8_t *state, int v, int is_signed){
+static av_noinline void put_symbol(RangeCoder *c, uint8_t *state, int v, int is_signed){
put_symbol_inline(c, state, v, is_signed, NULL, NULL);
}
}
}
-static int av_noinline get_symbol(RangeCoder *c, uint8_t *state, int is_signed){
+static av_noinline int get_symbol(RangeCoder *c, uint8_t *state, int is_signed){
return get_symbol_inline(c, state, is_signed);
}
}
#if CONFIG_FFV1_ENCODER
-static av_always_inline int encode_line(FFV1Context *s, int w, int_fast16_t *sample[2], int plane_index, int bits){
+static av_always_inline int encode_line(FFV1Context *s, int w,
+ int16_t *sample[3],
+ int plane_index, int bits)
+{
PlaneContext * const p= &s->plane[plane_index];
RangeCoder * const c= &s->c;
int x;
static void encode_plane(FFV1Context *s, uint8_t *src, int w, int h, int stride, int plane_index){
int x,y,i;
const int ring_size= s->avctx->context_model ? 3 : 2;
- int_fast16_t *sample[3];
+ int16_t *sample[3];
s->run_index=0;
memset(s->sample_buffer, 0, ring_size*(w+6)*sizeof(*s->sample_buffer));
static void encode_rgb_frame(FFV1Context *s, uint32_t *src, int w, int h, int stride){
int x, y, p, i;
const int ring_size= s->avctx->context_model ? 3 : 2;
- int_fast16_t *sample[3][3];
+ int16_t *sample[3][3];
s->run_index=0;
memset(s->sample_buffer, 0, ring_size*3*(w+6)*sizeof(*s->sample_buffer));
s->avctx= avctx;
s->flags= avctx->flags;
- dsputil_init(&s->dsp, avctx);
+ ff_dsputil_init(&s->dsp, avctx);
s->width = avctx->width;
s->height= avctx->height;
fs->slice_x = sxs;
fs->slice_y = sys;
- fs->sample_buffer = av_malloc(6 * (fs->width+6) * sizeof(*fs->sample_buffer));
+ fs->sample_buffer = av_malloc(9 * (fs->width+6) * sizeof(*fs->sample_buffer));
if (!fs->sample_buffer)
return AVERROR(ENOMEM);
}
return 0;
}
-static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){
+static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
+ const AVFrame *pict, int *got_packet)
+{
FFV1Context *f = avctx->priv_data;
RangeCoder * const c= &f->slice_context[0]->c;
- AVFrame *pict = data;
AVFrame * const p= &f->picture;
int used_count= 0;
uint8_t keystate=128;
uint8_t *buf_p;
- int i;
+ int i, ret;
+
+ if (!pkt->data &&
+ (ret = av_new_packet(pkt, avctx->width*avctx->height*((8*2+1+1)*4)/8
+ + FF_MIN_BUFFER_SIZE)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "Error getting output packet.\n");
+ return ret;
+ }
- ff_init_range_encoder(c, buf, buf_size);
+ ff_init_range_encoder(c, pkt->data, pkt->size);
ff_build_rac_states(c, 0.05*(1LL<<32), 256-8);
*p = *pict;
- p->pict_type= FF_I_TYPE;
+ p->pict_type= AV_PICTURE_TYPE_I;
if(avctx->gop_size==0 || f->picture_number % avctx->gop_size == 0){
put_rac(c, &keystate, 1);
if(!f->ac){
used_count += ff_rac_terminate(c);
//printf("pos=%d\n", used_count);
- init_put_bits(&f->slice_context[0]->pb, buf + used_count, buf_size - used_count);
+ init_put_bits(&f->slice_context[0]->pb, pkt->data + used_count, pkt->size - used_count);
}else if (f->ac>1){
int i;
for(i=1; i<256; i++){
for(i=1; i<f->slice_count; i++){
FFV1Context *fs= f->slice_context[i];
- uint8_t *start= buf + (buf_size-used_count)*i/f->slice_count;
- int len= buf_size/f->slice_count;
+ uint8_t *start = pkt->data + (pkt->size-used_count)*i/f->slice_count;
+ int len = pkt->size/f->slice_count;
if(fs->ac){
ff_init_range_encoder(&fs->c, start, len);
}
avctx->execute(avctx, encode_slice, &f->slice_context[0], NULL, f->slice_count, sizeof(void*));
- buf_p=buf;
+ buf_p = pkt->data;
for(i=0; i<f->slice_count; i++){
FFV1Context *fs= f->slice_context[i];
int bytes;
used_count= 0;
}
if(i>0){
- av_assert0(bytes < buf_size/f->slice_count);
+ av_assert0(bytes < pkt->size/f->slice_count);
memmove(buf_p, fs->ac ? fs->c.bytestream_start : fs->pb.buf, bytes);
av_assert0(bytes < (1<<24));
AV_WB24(buf_p+bytes, bytes);
avctx->stats_out[0] = '\0';
f->picture_number++;
- return buf_p-buf;
+ pkt->size = buf_p - pkt->data;
+ pkt->flags |= AV_PKT_FLAG_KEY*p->key_frame;
+ *got_packet = 1;
+
+ return 0;
}
#endif /* CONFIG_FFV1_ENCODER */
return 0;
}
-static av_always_inline void decode_line(FFV1Context *s, int w, int_fast16_t *sample[2], int plane_index, int bits){
+static av_always_inline void decode_line(FFV1Context *s, int w,
+ int16_t *sample[2],
+ int plane_index, int bits)
+{
PlaneContext * const p= &s->plane[plane_index];
RangeCoder * const c= &s->c;
int x;
static void decode_plane(FFV1Context *s, uint8_t *src, int w, int h, int stride, int plane_index){
int x, y;
- int_fast16_t *sample[2];
+ int16_t *sample[2];
sample[0]=s->sample_buffer +3;
sample[1]=s->sample_buffer+w+6+3;
memset(s->sample_buffer, 0, 2*(w+6)*sizeof(*s->sample_buffer));
for(y=0; y<h; y++){
- int_fast16_t *temp= sample[0]; //FIXME try a normal buffer
+ int16_t *temp = sample[0]; //FIXME try a normal buffer
sample[0]= sample[1];
sample[1]= temp;
static void decode_rgb_frame(FFV1Context *s, uint32_t *src, int w, int h, int stride){
int x, y, p;
- int_fast16_t *sample[3][2];
+ int16_t *sample[3][2];
for(x=0; x<3; x++){
sample[x][0] = s->sample_buffer + x*2 *(w+6) + 3;
sample[x][1] = s->sample_buffer + (x*2+1)*(w+6) + 3;
for(y=0; y<h; y++){
for(p=0; p<3; p++){
- int_fast16_t *temp= sample[p][0]; //FIXME try a normal buffer
+ int16_t *temp = sample[p][0]; //FIXME try a normal buffer
sample[p][0]= sample[p][1];
sample[p][1]= temp;
ff_build_rac_states(c, 0.05*(1LL<<32), 256-8);
- p->pict_type= FF_I_TYPE; //FIXME I vs. P
+ p->pict_type= AV_PICTURE_TYPE_I; //FIXME I vs. P
if(get_rac(c, &keystate)){
p->key_frame= 1;
if(read_header(f) < 0)
bytes_read = c->bytestream - c->bytestream_start - 1;
if(bytes_read ==0) av_log(avctx, AV_LOG_ERROR, "error at end of AC stream\n"); //FIXME
//printf("pos=%d\n", bytes_read);
- init_get_bits(&f->slice_context[0]->gb, buf + bytes_read, buf_size - bytes_read);
+ init_get_bits(&f->slice_context[0]->gb, buf + bytes_read, (buf_size - bytes_read) * 8);
} else {
bytes_read = 0; /* avoid warning */
}
if(fs->ac){
ff_init_range_decoder(&fs->c, buf_p, v);
}else{
- init_get_bits(&fs->gb, buf_p, v);
+ init_get_bits(&fs->gb, buf_p, v * 8);
}
}
}
AVCodec ff_ffv1_decoder = {
- "ffv1",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_FFV1,
- sizeof(FFV1Context),
- decode_init,
- NULL,
- common_end,
- decode_frame,
- CODEC_CAP_DR1 /*| CODEC_CAP_DRAW_HORIZ_BAND*/,
- NULL,
- .long_name= NULL_IF_CONFIG_SMALL("FFmpeg video codec #1"),
+ .name = "ffv1",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_FFV1,
+ .priv_data_size = sizeof(FFV1Context),
+ .init = decode_init,
+ .close = common_end,
+ .decode = decode_frame,
+ .capabilities = CODEC_CAP_DR1 /*| CODEC_CAP_DRAW_HORIZ_BAND*/ |
+ CODEC_CAP_SLICE_THREADS,
+ .long_name = NULL_IF_CONFIG_SMALL("FFmpeg video codec #1"),
};
#if CONFIG_FFV1_ENCODER
AVCodec ff_ffv1_encoder = {
- "ffv1",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_FFV1,
- sizeof(FFV1Context),
- encode_init,
- encode_frame,
- common_end,
- .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_YUV444P, PIX_FMT_YUV422P, PIX_FMT_YUV411P, PIX_FMT_YUV410P, PIX_FMT_RGB32, PIX_FMT_YUV420P16, PIX_FMT_YUV422P16, PIX_FMT_YUV444P16, PIX_FMT_NONE},
- .long_name= NULL_IF_CONFIG_SMALL("FFmpeg video codec #1"),
+ .name = "ffv1",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_FFV1,
+ .priv_data_size = sizeof(FFV1Context),
+ .init = encode_init,
+ .encode2 = encode_frame,
+ .close = common_end,
+ .capabilities = CODEC_CAP_SLICE_THREADS,
+ .pix_fmts = (const enum PixelFormat[]){
+ PIX_FMT_YUV420P, PIX_FMT_YUV444P, PIX_FMT_YUV422P, PIX_FMT_YUV411P,
+ PIX_FMT_YUV410P, PIX_FMT_RGB32, PIX_FMT_YUV420P16, PIX_FMT_YUV422P16,
+ PIX_FMT_YUV444P16, PIX_FMT_NONE
+ },
+ .long_name = NULL_IF_CONFIG_SMALL("FFmpeg video codec #1"),
};
#endif