Update avcodec to 20080825
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27549 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
c6ecd9c8dc
commit
30dd64ce04
54
src/add-ons/media/plugins/avcodec/libavcodec/h261.c
Normal file
54
src/add-ons/media/plugins/avcodec/libavcodec/h261.c
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* H261 common code
|
||||
* Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
|
||||
* Copyright (c) 2004 Maarten Daniels
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg 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,
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file h261.c
|
||||
* h261codec.
|
||||
*/
|
||||
|
||||
#include "dsputil.h"
|
||||
#include "avcodec.h"
|
||||
#include "h261.h"
|
||||
|
||||
#define IS_FIL(a) ((a)&MB_TYPE_H261_FIL)
|
||||
|
||||
uint8_t ff_h261_rl_table_store[2][2*MAX_RUN + MAX_LEVEL + 3];
|
||||
|
||||
void ff_h261_loop_filter(MpegEncContext *s){
|
||||
H261Context * h= (H261Context*)s;
|
||||
const int linesize = s->linesize;
|
||||
const int uvlinesize= s->uvlinesize;
|
||||
uint8_t *dest_y = s->dest[0];
|
||||
uint8_t *dest_cb= s->dest[1];
|
||||
uint8_t *dest_cr= s->dest[2];
|
||||
|
||||
if(!(IS_FIL (h->mtype)))
|
||||
return;
|
||||
|
||||
s->dsp.h261_loop_filter(dest_y , linesize);
|
||||
s->dsp.h261_loop_filter(dest_y + 8, linesize);
|
||||
s->dsp.h261_loop_filter(dest_y + 8 * linesize , linesize);
|
||||
s->dsp.h261_loop_filter(dest_y + 8 * linesize + 8, linesize);
|
||||
s->dsp.h261_loop_filter(dest_cb, uvlinesize);
|
||||
s->dsp.h261_loop_filter(dest_cr, uvlinesize);
|
||||
}
|
||||
|
51
src/add-ons/media/plugins/avcodec/libavcodec/h261.h
Normal file
51
src/add-ons/media/plugins/avcodec/libavcodec/h261.h
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* H261 decoder
|
||||
* Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
|
||||
* Copyright (c) 2004 Maarten Daniels
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg 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,
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file h261.c
|
||||
* h261codec.
|
||||
*/
|
||||
|
||||
#ifndef FFMPEG_H261_H
|
||||
#define FFMPEG_H261_H
|
||||
|
||||
#include "mpegvideo.h"
|
||||
|
||||
/**
|
||||
* H261Context
|
||||
*/
|
||||
typedef struct H261Context{
|
||||
MpegEncContext s;
|
||||
|
||||
int current_mba;
|
||||
int previous_mba;
|
||||
int mba_diff;
|
||||
int mtype;
|
||||
int current_mv_x;
|
||||
int current_mv_y;
|
||||
int gob_number;
|
||||
int gob_start_code_skipped; // 1 if gob start code is already read before gob header is read
|
||||
}H261Context;
|
||||
|
||||
#define MB_TYPE_H261_FIL 0x800000
|
||||
|
||||
#endif /* FFMPEG_H261_H */
|
90
src/add-ons/media/plugins/avcodec/libavcodec/h261_parser.c
Normal file
90
src/add-ons/media/plugins/avcodec/libavcodec/h261_parser.c
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* H261 parser
|
||||
* Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
|
||||
* Copyright (c) 2004 Maarten Daniels
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg 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,
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file h261_parser.c
|
||||
* h261codec.
|
||||
*/
|
||||
|
||||
#include "parser.h"
|
||||
|
||||
|
||||
static int h261_find_frame_end(ParseContext *pc, AVCodecContext* avctx, const uint8_t *buf, int buf_size){
|
||||
int vop_found, i, j;
|
||||
uint32_t state;
|
||||
|
||||
vop_found= pc->frame_start_found;
|
||||
state= pc->state;
|
||||
|
||||
for(i=0; i<buf_size && !vop_found; i++){
|
||||
state= (state<<8) | buf[i];
|
||||
for(j=0; j<8; j++){
|
||||
if(((state>>j)&0xFFFFF0) == 0x000100){
|
||||
vop_found=1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(vop_found){
|
||||
for(; i<buf_size; i++){
|
||||
state= (state<<8) | buf[i];
|
||||
for(j=0; j<8; j++){
|
||||
if(((state>>j)&0xFFFFF0) == 0x000100){
|
||||
pc->frame_start_found=0;
|
||||
pc->state= (state>>(3*8))+0xFF00;
|
||||
return i-2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pc->frame_start_found= vop_found;
|
||||
pc->state= state;
|
||||
return END_NOT_FOUND;
|
||||
}
|
||||
|
||||
static int h261_parse(AVCodecParserContext *s,
|
||||
AVCodecContext *avctx,
|
||||
const uint8_t **poutbuf, int *poutbuf_size,
|
||||
const uint8_t *buf, int buf_size)
|
||||
{
|
||||
ParseContext *pc = s->priv_data;
|
||||
int next;
|
||||
|
||||
next= h261_find_frame_end(pc,avctx, buf, buf_size);
|
||||
if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
|
||||
*poutbuf = NULL;
|
||||
*poutbuf_size = 0;
|
||||
return buf_size;
|
||||
}
|
||||
*poutbuf = buf;
|
||||
*poutbuf_size = buf_size;
|
||||
return next;
|
||||
}
|
||||
|
||||
AVCodecParser h261_parser = {
|
||||
{ CODEC_ID_H261 },
|
||||
sizeof(ParseContext),
|
||||
NULL,
|
||||
h261_parse,
|
||||
ff_parse_close,
|
||||
};
|
164
src/add-ons/media/plugins/avcodec/libavcodec/h261data.h
Normal file
164
src/add-ons/media/plugins/avcodec/libavcodec/h261data.h
Normal file
@ -0,0 +1,164 @@
|
||||
/*
|
||||
* copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
|
||||
* copyright (c) 2004 Maarten Daniels
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg 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,
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file h261data.h
|
||||
* H.261 tables.
|
||||
*/
|
||||
|
||||
#ifndef FFMPEG_H261DATA_H
|
||||
#define FFMPEG_H261DATA_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "h261.h"
|
||||
|
||||
// H.261 VLC table for macroblock addressing
|
||||
static const uint8_t h261_mba_code[35] = {
|
||||
1, 3, 2, 3,
|
||||
2, 3, 2, 7,
|
||||
6, 11, 10, 9,
|
||||
8, 7, 6, 23,
|
||||
22, 21, 20, 19,
|
||||
18, 35, 34, 33,
|
||||
32, 31, 30, 29,
|
||||
28, 27, 26, 25,
|
||||
24,
|
||||
15, //(MBA stuffing)
|
||||
1 //(start code)
|
||||
};
|
||||
|
||||
static const uint8_t h261_mba_bits[35] = {
|
||||
1, 3, 3, 4,
|
||||
4, 5, 5, 7,
|
||||
7, 8, 8, 8,
|
||||
8, 8, 8, 10,
|
||||
10, 10, 10, 10,
|
||||
10, 11, 11, 11,
|
||||
11, 11, 11, 11,
|
||||
11, 11, 11, 11,
|
||||
11,
|
||||
11, //(MBA stuffing)
|
||||
16 //(start code)
|
||||
};
|
||||
|
||||
//H.261 VLC table for macroblock type
|
||||
static const uint8_t h261_mtype_code[10] = {
|
||||
1, 1, 1, 1,
|
||||
1, 1, 1, 1,
|
||||
1, 1
|
||||
};
|
||||
|
||||
static const uint8_t h261_mtype_bits[10] = {
|
||||
4, 7, 1, 5,
|
||||
9, 8, 10, 3,
|
||||
2, 6
|
||||
};
|
||||
|
||||
static const int h261_mtype_map[10]= {
|
||||
MB_TYPE_INTRA4x4,
|
||||
MB_TYPE_INTRA4x4 | MB_TYPE_QUANT,
|
||||
MB_TYPE_CBP,
|
||||
MB_TYPE_QUANT | MB_TYPE_CBP,
|
||||
MB_TYPE_16x16,
|
||||
MB_TYPE_CBP | MB_TYPE_16x16,
|
||||
MB_TYPE_QUANT | MB_TYPE_CBP | MB_TYPE_16x16,
|
||||
MB_TYPE_16x16 | MB_TYPE_H261_FIL,
|
||||
MB_TYPE_CBP | MB_TYPE_16x16 | MB_TYPE_H261_FIL,
|
||||
MB_TYPE_QUANT | MB_TYPE_CBP | MB_TYPE_16x16 | MB_TYPE_H261_FIL
|
||||
};
|
||||
|
||||
//H.261 VLC table for motion vectors
|
||||
static const uint8_t h261_mv_tab[17][2] = {
|
||||
{1,1}, {1,2}, {1,3}, {1,4}, {3,6}, {5,7}, {4,7}, {3,7},
|
||||
{11,9}, {10,9}, {9,9}, {17,10}, {16,10}, {15,10}, {14,10}, {13,10}, {12,10}
|
||||
};
|
||||
|
||||
static const int mvmap[17] =
|
||||
{
|
||||
0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15, -16
|
||||
};
|
||||
|
||||
//H.261 VLC table for coded block pattern
|
||||
static const uint8_t h261_cbp_tab[63][2] =
|
||||
{
|
||||
{11,5}, {9,5}, {13,6}, {13,4}, {23,7}, {19,7}, {31,8}, {12,4},
|
||||
{22,7}, {18,7}, {30,8}, {19,5}, {27,8}, {23,8}, {19,8}, {11,4},
|
||||
{21,7}, {17,7}, {29,8}, {17,5}, {25,8}, {21,8}, {17,8}, {15,6},
|
||||
{15,8}, {13,8}, {3,9}, {15,5}, {11,8}, {7,8}, {7,9}, {10,4},
|
||||
{20,7}, {16,7}, {28,8}, {14,6}, {14,8}, {12,8}, {2,9}, {16,5},
|
||||
{24,8}, {20,8}, {16,8}, {14,5}, {10,8}, {6,8}, {6,9}, {18,5},
|
||||
{26,8}, {22,8}, {18,8}, {13,5}, {9,8}, {5,8}, {5,9}, {12,5},
|
||||
{8,8}, {4,8}, {4,9}, {7,3}, {10,5}, {8,5}, {12,6}
|
||||
};
|
||||
|
||||
//H.261 VLC table for transform coefficients
|
||||
static const uint16_t h261_tcoeff_vlc[65][2] = {
|
||||
{ 0x2, 2 }, { 0x3, 2 },{ 0x4, 4 },{ 0x5, 5 },
|
||||
{ 0x6, 7 },{ 0x26, 8 },{ 0x21, 8 },{ 0xa, 10 },
|
||||
{ 0x1d, 12 },{ 0x18, 12 },{ 0x13, 12 },{ 0x10 , 12 },
|
||||
{ 0x1a, 13},{ 0x19, 13 }, { 0x18, 13 }, { 0x17, 13 },
|
||||
{ 0x3, 3 }, { 0x6, 6 }, { 0x25 , 8 }, { 0xc, 10 },
|
||||
{ 0x1b, 12 }, { 0x16, 13 }, { 0x15, 13 }, { 0x5, 4},
|
||||
{ 0x4, 7}, { 0xb, 10 }, { 0x14, 12 }, { 0x14, 13 },
|
||||
{ 0x7, 5 }, { 0x24, 8 }, { 0x1c, 12 }, { 0x13, 13 },
|
||||
{ 0x6, 5 }, { 0xf, 10 }, { 0x12, 12}, { 0x7, 6},
|
||||
{ 0x9 , 10 }, { 0x12, 13 }, { 0x5, 6 }, { 0x1e, 12 },
|
||||
{ 0x4, 6 }, { 0x15, 12 }, { 0x7, 7 }, { 0x11, 12},
|
||||
{ 0x5, 7 }, { 0x11, 13 }, { 0x27, 8 }, { 0x10, 13 },
|
||||
{ 0x23, 8 }, { 0x22, 8 }, { 0x20, 8 }, { 0xe , 10 },
|
||||
{ 0xd, 10 }, { 0x8, 10 },{ 0x1f, 12 }, { 0x1a, 12 },
|
||||
{ 0x19, 12 }, { 0x17, 12 }, { 0x16, 12}, { 0x1f, 13},
|
||||
{ 0x1e, 13 }, { 0x1d, 13 }, { 0x1c, 13}, { 0x1b, 13},
|
||||
{ 0x1, 6 } //escape
|
||||
};
|
||||
|
||||
static const int8_t h261_tcoeff_level[64] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7,
|
||||
8, 9, 10, 11, 12, 13, 14, 15,
|
||||
1, 2, 3, 4, 5, 6, 7, 1,
|
||||
2, 3, 4, 5, 1, 2, 3, 4,
|
||||
1, 2, 3, 1, 2, 3, 1, 2,
|
||||
1, 2, 1, 2, 1, 2, 1, 2,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1
|
||||
};
|
||||
|
||||
static const int8_t h261_tcoeff_run[64] = {
|
||||
0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 1,
|
||||
1, 1, 1, 1, 1, 1, 2, 2,
|
||||
2, 2, 2, 3, 3, 3, 3, 4,
|
||||
4, 4, 5, 5, 5, 6, 6, 7,
|
||||
7, 8, 8, 9, 9, 10, 10, 11,
|
||||
12, 13, 14, 15, 16, 17, 18, 19,
|
||||
20, 21, 22, 23, 24, 25, 26
|
||||
};
|
||||
|
||||
static RLTable h261_rl_tcoeff = {
|
||||
64,
|
||||
64,
|
||||
h261_tcoeff_vlc,
|
||||
h261_tcoeff_run,
|
||||
h261_tcoeff_level,
|
||||
};
|
||||
|
||||
#endif /* FFMPEG_H261DATA_H */
|
654
src/add-ons/media/plugins/avcodec/libavcodec/h261dec.c
Normal file
654
src/add-ons/media/plugins/avcodec/libavcodec/h261dec.c
Normal file
@ -0,0 +1,654 @@
|
||||
/*
|
||||
* H261 decoder
|
||||
* Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
|
||||
* Copyright (c) 2004 Maarten Daniels
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg 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,
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file h261dec.c
|
||||
* H.261 decoder.
|
||||
*/
|
||||
|
||||
#include "dsputil.h"
|
||||
#include "avcodec.h"
|
||||
#include "mpegvideo.h"
|
||||
#include "h261.h"
|
||||
#include "h261data.h"
|
||||
|
||||
#define H261_MBA_VLC_BITS 9
|
||||
#define H261_MTYPE_VLC_BITS 6
|
||||
#define H261_MV_VLC_BITS 7
|
||||
#define H261_CBP_VLC_BITS 9
|
||||
#define TCOEFF_VLC_BITS 9
|
||||
#define MBA_STUFFING 33
|
||||
#define MBA_STARTCODE 34
|
||||
|
||||
extern uint8_t ff_h261_rl_table_store[2][2*MAX_RUN + MAX_LEVEL + 3];
|
||||
|
||||
static VLC h261_mba_vlc;
|
||||
static VLC h261_mtype_vlc;
|
||||
static VLC h261_mv_vlc;
|
||||
static VLC h261_cbp_vlc;
|
||||
|
||||
static int h261_decode_block(H261Context * h, DCTELEM * block, int n, int coded);
|
||||
|
||||
static av_cold void h261_decode_init_vlc(H261Context *h){
|
||||
static int done = 0;
|
||||
|
||||
if(!done){
|
||||
done = 1;
|
||||
init_vlc(&h261_mba_vlc, H261_MBA_VLC_BITS, 35,
|
||||
h261_mba_bits, 1, 1,
|
||||
h261_mba_code, 1, 1, 1);
|
||||
init_vlc(&h261_mtype_vlc, H261_MTYPE_VLC_BITS, 10,
|
||||
h261_mtype_bits, 1, 1,
|
||||
h261_mtype_code, 1, 1, 1);
|
||||
init_vlc(&h261_mv_vlc, H261_MV_VLC_BITS, 17,
|
||||
&h261_mv_tab[0][1], 2, 1,
|
||||
&h261_mv_tab[0][0], 2, 1, 1);
|
||||
init_vlc(&h261_cbp_vlc, H261_CBP_VLC_BITS, 63,
|
||||
&h261_cbp_tab[0][1], 2, 1,
|
||||
&h261_cbp_tab[0][0], 2, 1, 1);
|
||||
init_rl(&h261_rl_tcoeff, ff_h261_rl_table_store);
|
||||
INIT_VLC_RL(h261_rl_tcoeff, 552);
|
||||
}
|
||||
}
|
||||
|
||||
static av_cold int h261_decode_init(AVCodecContext *avctx){
|
||||
H261Context *h= avctx->priv_data;
|
||||
MpegEncContext * const s = &h->s;
|
||||
|
||||
// set defaults
|
||||
MPV_decode_defaults(s);
|
||||
s->avctx = avctx;
|
||||
|
||||
s->width = s->avctx->coded_width;
|
||||
s->height = s->avctx->coded_height;
|
||||
s->codec_id = s->avctx->codec->id;
|
||||
|
||||
s->out_format = FMT_H261;
|
||||
s->low_delay= 1;
|
||||
avctx->pix_fmt= PIX_FMT_YUV420P;
|
||||
|
||||
s->codec_id= avctx->codec->id;
|
||||
|
||||
h261_decode_init_vlc(h);
|
||||
|
||||
h->gob_start_code_skipped = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* decodes the group of blocks header or slice header.
|
||||
* @return <0 if an error occurred
|
||||
*/
|
||||
static int h261_decode_gob_header(H261Context *h){
|
||||
unsigned int val;
|
||||
MpegEncContext * const s = &h->s;
|
||||
|
||||
if ( !h->gob_start_code_skipped ){
|
||||
/* Check for GOB Start Code */
|
||||
val = show_bits(&s->gb, 15);
|
||||
if(val)
|
||||
return -1;
|
||||
|
||||
/* We have a GBSC */
|
||||
skip_bits(&s->gb, 16);
|
||||
}
|
||||
|
||||
h->gob_start_code_skipped = 0;
|
||||
|
||||
h->gob_number = get_bits(&s->gb, 4); /* GN */
|
||||
s->qscale = get_bits(&s->gb, 5); /* GQUANT */
|
||||
|
||||
/* Check if gob_number is valid */
|
||||
if (s->mb_height==18){ //cif
|
||||
if ((h->gob_number<=0) || (h->gob_number>12))
|
||||
return -1;
|
||||
}
|
||||
else{ //qcif
|
||||
if ((h->gob_number!=1) && (h->gob_number!=3) && (h->gob_number!=5))
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* GEI */
|
||||
while (get_bits1(&s->gb) != 0) {
|
||||
skip_bits(&s->gb, 8);
|
||||
}
|
||||
|
||||
if(s->qscale==0) {
|
||||
av_log(s->avctx, AV_LOG_ERROR, "qscale has forbidden 0 value\n");
|
||||
if (s->avctx->error_resilience >= FF_ER_COMPLIANT)
|
||||
return -1;
|
||||
}
|
||||
|
||||
// For the first transmitted macroblock in a GOB, MBA is the absolute address. For
|
||||
// subsequent macroblocks, MBA is the difference between the absolute addresses of
|
||||
// the macroblock and the last transmitted macroblock.
|
||||
h->current_mba = 0;
|
||||
h->mba_diff = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* decodes the group of blocks / video packet header.
|
||||
* @return <0 if no resync found
|
||||
*/
|
||||
static int ff_h261_resync(H261Context *h){
|
||||
MpegEncContext * const s = &h->s;
|
||||
int left, ret;
|
||||
|
||||
if ( h->gob_start_code_skipped ){
|
||||
ret= h261_decode_gob_header(h);
|
||||
if(ret>=0)
|
||||
return 0;
|
||||
}
|
||||
else{
|
||||
if(show_bits(&s->gb, 15)==0){
|
||||
ret= h261_decode_gob_header(h);
|
||||
if(ret>=0)
|
||||
return 0;
|
||||
}
|
||||
//OK, it is not where it is supposed to be ...
|
||||
s->gb= s->last_resync_gb;
|
||||
align_get_bits(&s->gb);
|
||||
left= s->gb.size_in_bits - get_bits_count(&s->gb);
|
||||
|
||||
for(;left>15+1+4+5; left-=8){
|
||||
if(show_bits(&s->gb, 15)==0){
|
||||
GetBitContext bak= s->gb;
|
||||
|
||||
ret= h261_decode_gob_header(h);
|
||||
if(ret>=0)
|
||||
return 0;
|
||||
|
||||
s->gb= bak;
|
||||
}
|
||||
skip_bits(&s->gb, 8);
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* decodes skipped macroblocks
|
||||
* @return 0
|
||||
*/
|
||||
static int h261_decode_mb_skipped(H261Context *h, int mba1, int mba2 )
|
||||
{
|
||||
MpegEncContext * const s = &h->s;
|
||||
int i;
|
||||
|
||||
s->mb_intra = 0;
|
||||
|
||||
for(i=mba1; i<mba2; i++){
|
||||
int j, xy;
|
||||
|
||||
s->mb_x= ((h->gob_number-1) % 2) * 11 + i % 11;
|
||||
s->mb_y= ((h->gob_number-1) / 2) * 3 + i / 11;
|
||||
xy = s->mb_x + s->mb_y * s->mb_stride;
|
||||
ff_init_block_index(s);
|
||||
ff_update_block_index(s);
|
||||
|
||||
for(j=0;j<6;j++)
|
||||
s->block_last_index[j] = -1;
|
||||
|
||||
s->mv_dir = MV_DIR_FORWARD;
|
||||
s->mv_type = MV_TYPE_16X16;
|
||||
s->current_picture.mb_type[xy]= MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0;
|
||||
s->mv[0][0][0] = 0;
|
||||
s->mv[0][0][1] = 0;
|
||||
s->mb_skipped = 1;
|
||||
h->mtype &= ~MB_TYPE_H261_FIL;
|
||||
|
||||
MPV_decode_mb(s, s->block);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int decode_mv_component(GetBitContext *gb, int v){
|
||||
int mv_diff = get_vlc2(gb, h261_mv_vlc.table, H261_MV_VLC_BITS, 2);
|
||||
|
||||
/* check if mv_diff is valid */
|
||||
if ( mv_diff < 0 )
|
||||
return v;
|
||||
|
||||
mv_diff = mvmap[mv_diff];
|
||||
|
||||
if(mv_diff && !get_bits1(gb))
|
||||
mv_diff= -mv_diff;
|
||||
|
||||
v += mv_diff;
|
||||
if (v <=-16) v+= 32;
|
||||
else if(v >= 16) v-= 32;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
static int h261_decode_mb(H261Context *h){
|
||||
MpegEncContext * const s = &h->s;
|
||||
int i, cbp, xy;
|
||||
|
||||
cbp = 63;
|
||||
// Read mba
|
||||
do{
|
||||
h->mba_diff = get_vlc2(&s->gb, h261_mba_vlc.table, H261_MBA_VLC_BITS, 2);
|
||||
|
||||
/* Check for slice end */
|
||||
/* NOTE: GOB can be empty (no MB data) or exist only of MBA_stuffing */
|
||||
if (h->mba_diff == MBA_STARTCODE){ // start code
|
||||
h->gob_start_code_skipped = 1;
|
||||
return SLICE_END;
|
||||
}
|
||||
}
|
||||
while( h->mba_diff == MBA_STUFFING ); // stuffing
|
||||
|
||||
if ( h->mba_diff < 0 ){
|
||||
if ( get_bits_count(&s->gb) + 7 >= s->gb.size_in_bits )
|
||||
return SLICE_END;
|
||||
|
||||
av_log(s->avctx, AV_LOG_ERROR, "illegal mba at %d %d\n", s->mb_x, s->mb_y);
|
||||
return SLICE_ERROR;
|
||||
}
|
||||
|
||||
h->mba_diff += 1;
|
||||
h->current_mba += h->mba_diff;
|
||||
|
||||
if ( h->current_mba > MBA_STUFFING )
|
||||
return SLICE_ERROR;
|
||||
|
||||
s->mb_x= ((h->gob_number-1) % 2) * 11 + ((h->current_mba-1) % 11);
|
||||
s->mb_y= ((h->gob_number-1) / 2) * 3 + ((h->current_mba-1) / 11);
|
||||
xy = s->mb_x + s->mb_y * s->mb_stride;
|
||||
ff_init_block_index(s);
|
||||
ff_update_block_index(s);
|
||||
|
||||
// Read mtype
|
||||
h->mtype = get_vlc2(&s->gb, h261_mtype_vlc.table, H261_MTYPE_VLC_BITS, 2);
|
||||
h->mtype = h261_mtype_map[h->mtype];
|
||||
|
||||
// Read mquant
|
||||
if ( IS_QUANT ( h->mtype ) ){
|
||||
ff_set_qscale(s, get_bits(&s->gb, 5));
|
||||
}
|
||||
|
||||
s->mb_intra = IS_INTRA4x4(h->mtype);
|
||||
|
||||
// Read mv
|
||||
if ( IS_16X16 ( h->mtype ) ){
|
||||
// Motion vector data is included for all MC macroblocks. MVD is obtained from the macroblock vector by subtracting the
|
||||
// vector of the preceding macroblock. For this calculation the vector of the preceding macroblock is regarded as zero in the
|
||||
// following three situations:
|
||||
// 1) evaluating MVD for macroblocks 1, 12 and 23;
|
||||
// 2) evaluating MVD for macroblocks in which MBA does not represent a difference of 1;
|
||||
// 3) MTYPE of the previous macroblock was not MC.
|
||||
if ( ( h->current_mba == 1 ) || ( h->current_mba == 12 ) || ( h->current_mba == 23 ) ||
|
||||
( h->mba_diff != 1))
|
||||
{
|
||||
h->current_mv_x = 0;
|
||||
h->current_mv_y = 0;
|
||||
}
|
||||
|
||||
h->current_mv_x= decode_mv_component(&s->gb, h->current_mv_x);
|
||||
h->current_mv_y= decode_mv_component(&s->gb, h->current_mv_y);
|
||||
}else{
|
||||
h->current_mv_x = 0;
|
||||
h->current_mv_y = 0;
|
||||
}
|
||||
|
||||
// Read cbp
|
||||
if ( HAS_CBP( h->mtype ) ){
|
||||
cbp = get_vlc2(&s->gb, h261_cbp_vlc.table, H261_CBP_VLC_BITS, 2) + 1;
|
||||
}
|
||||
|
||||
if(s->mb_intra){
|
||||
s->current_picture.mb_type[xy]= MB_TYPE_INTRA;
|
||||
goto intra;
|
||||
}
|
||||
|
||||
//set motion vectors
|
||||
s->mv_dir = MV_DIR_FORWARD;
|
||||
s->mv_type = MV_TYPE_16X16;
|
||||
s->current_picture.mb_type[xy]= MB_TYPE_16x16 | MB_TYPE_L0;
|
||||
s->mv[0][0][0] = h->current_mv_x * 2;//gets divided by 2 in motion compensation
|
||||
s->mv[0][0][1] = h->current_mv_y * 2;
|
||||
|
||||
intra:
|
||||
/* decode each block */
|
||||
if(s->mb_intra || HAS_CBP(h->mtype)){
|
||||
s->dsp.clear_blocks(s->block[0]);
|
||||
for (i = 0; i < 6; i++) {
|
||||
if (h261_decode_block(h, s->block[i], i, cbp&32) < 0){
|
||||
return SLICE_ERROR;
|
||||
}
|
||||
cbp+=cbp;
|
||||
}
|
||||
}else{
|
||||
for (i = 0; i < 6; i++)
|
||||
s->block_last_index[i]= -1;
|
||||
}
|
||||
|
||||
MPV_decode_mb(s, s->block);
|
||||
|
||||
return SLICE_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* decodes a macroblock
|
||||
* @return <0 if an error occurred
|
||||
*/
|
||||
static int h261_decode_block(H261Context * h, DCTELEM * block,
|
||||
int n, int coded)
|
||||
{
|
||||
MpegEncContext * const s = &h->s;
|
||||
int code, level, i, j, run;
|
||||
RLTable *rl = &h261_rl_tcoeff;
|
||||
const uint8_t *scan_table;
|
||||
|
||||
// For the variable length encoding there are two code tables, one being used for
|
||||
// the first transmitted LEVEL in INTER, INTER+MC and INTER+MC+FIL blocks, the second
|
||||
// for all other LEVELs except the first one in INTRA blocks which is fixed length
|
||||
// coded with 8 bits.
|
||||
// NOTE: the two code tables only differ in one VLC so we handle that manually.
|
||||
scan_table = s->intra_scantable.permutated;
|
||||
if (s->mb_intra){
|
||||
/* DC coef */
|
||||
level = get_bits(&s->gb, 8);
|
||||
// 0 (00000000b) and -128 (10000000b) are FORBIDDEN
|
||||
if((level&0x7F) == 0){
|
||||
av_log(s->avctx, AV_LOG_ERROR, "illegal dc %d at %d %d\n", level, s->mb_x, s->mb_y);
|
||||
return -1;
|
||||
}
|
||||
// The code 1000 0000 is not used, the reconstruction level of 1024 being coded as 1111 1111.
|
||||
if (level == 255)
|
||||
level = 128;
|
||||
block[0] = level;
|
||||
i = 1;
|
||||
}else if(coded){
|
||||
// Run Level Code
|
||||
// EOB Not possible for first level when cbp is available (that's why the table is different)
|
||||
// 0 1 1s
|
||||
// * * 0*
|
||||
int check = show_bits(&s->gb, 2);
|
||||
i = 0;
|
||||
if ( check & 0x2 ){
|
||||
skip_bits(&s->gb, 2);
|
||||
block[0] = ( check & 0x1 ) ? -1 : 1;
|
||||
i = 1;
|
||||
}
|
||||
}else{
|
||||
i = 0;
|
||||
}
|
||||
if(!coded){
|
||||
s->block_last_index[n] = i - 1;
|
||||
return 0;
|
||||
}
|
||||
for(;;){
|
||||
code = get_vlc2(&s->gb, rl->vlc.table, TCOEFF_VLC_BITS, 2);
|
||||
if (code < 0){
|
||||
av_log(s->avctx, AV_LOG_ERROR, "illegal ac vlc code at %dx%d\n", s->mb_x, s->mb_y);
|
||||
return -1;
|
||||
}
|
||||
if (code == rl->n) {
|
||||
/* escape */
|
||||
// The remaining combinations of (run, level) are encoded with a 20-bit word consisting of 6 bits escape, 6 bits run and 8 bits level.
|
||||
run = get_bits(&s->gb, 6);
|
||||
level = get_sbits(&s->gb, 8);
|
||||
}else if(code == 0){
|
||||
break;
|
||||
}else{
|
||||
run = rl->table_run[code];
|
||||
level = rl->table_level[code];
|
||||
if (get_bits1(&s->gb))
|
||||
level = -level;
|
||||
}
|
||||
i += run;
|
||||
if (i >= 64){
|
||||
av_log(s->avctx, AV_LOG_ERROR, "run overflow at %dx%d\n", s->mb_x, s->mb_y);
|
||||
return -1;
|
||||
}
|
||||
j = scan_table[i];
|
||||
block[j] = level;
|
||||
i++;
|
||||
}
|
||||
s->block_last_index[n] = i-1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* decodes the H261 picture header.
|
||||
* @return <0 if no startcode found
|
||||
*/
|
||||
static int h261_decode_picture_header(H261Context *h){
|
||||
MpegEncContext * const s = &h->s;
|
||||
int format, i;
|
||||
uint32_t startcode= 0;
|
||||
|
||||
for(i= s->gb.size_in_bits - get_bits_count(&s->gb); i>24; i-=1){
|
||||
startcode = ((startcode << 1) | get_bits(&s->gb, 1)) & 0x000FFFFF;
|
||||
|
||||
if(startcode == 0x10)
|
||||
break;
|
||||
}
|
||||
|
||||
if (startcode != 0x10){
|
||||
av_log(s->avctx, AV_LOG_ERROR, "Bad picture start code\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* temporal reference */
|
||||
i= get_bits(&s->gb, 5); /* picture timestamp */
|
||||
if(i < (s->picture_number&31))
|
||||
i += 32;
|
||||
s->picture_number = (s->picture_number&~31) + i;
|
||||
|
||||
s->avctx->time_base= (AVRational){1001, 30000};
|
||||
s->current_picture.pts= s->picture_number;
|
||||
|
||||
|
||||
/* PTYPE starts here */
|
||||
skip_bits1(&s->gb); /* split screen off */
|
||||
skip_bits1(&s->gb); /* camera off */
|
||||
skip_bits1(&s->gb); /* freeze picture release off */
|
||||
|
||||
format = get_bits1(&s->gb);
|
||||
|
||||
//only 2 formats possible
|
||||
if (format == 0){//QCIF
|
||||
s->width = 176;
|
||||
s->height = 144;
|
||||
s->mb_width = 11;
|
||||
s->mb_height = 9;
|
||||
}else{//CIF
|
||||
s->width = 352;
|
||||
s->height = 288;
|
||||
s->mb_width = 22;
|
||||
s->mb_height = 18;
|
||||
}
|
||||
|
||||
s->mb_num = s->mb_width * s->mb_height;
|
||||
|
||||
skip_bits1(&s->gb); /* still image mode off */
|
||||
skip_bits1(&s->gb); /* Reserved */
|
||||
|
||||
/* PEI */
|
||||
while (get_bits1(&s->gb) != 0){
|
||||
skip_bits(&s->gb, 8);
|
||||
}
|
||||
|
||||
// h261 has no I-FRAMES, but if we pass FF_I_TYPE for the first frame, the codec crashes if it does
|
||||
// not contain all I-blocks (e.g. when a packet is lost)
|
||||
s->pict_type = FF_P_TYPE;
|
||||
|
||||
h->gob_number = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int h261_decode_gob(H261Context *h){
|
||||
MpegEncContext * const s = &h->s;
|
||||
|
||||
ff_set_qscale(s, s->qscale);
|
||||
|
||||
/* decode mb's */
|
||||
while(h->current_mba <= MBA_STUFFING)
|
||||
{
|
||||
int ret;
|
||||
/* DCT & quantize */
|
||||
ret= h261_decode_mb(h);
|
||||
if(ret<0){
|
||||
if(ret==SLICE_END){
|
||||
h261_decode_mb_skipped(h, h->current_mba, 33);
|
||||
return 0;
|
||||
}
|
||||
av_log(s->avctx, AV_LOG_ERROR, "Error at MB: %d\n", s->mb_x + s->mb_y*s->mb_stride);
|
||||
return -1;
|
||||
}
|
||||
|
||||
h261_decode_mb_skipped(h, h->current_mba-h->mba_diff, h->current_mba-1);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the number of bytes consumed for building the current frame
|
||||
*/
|
||||
static int get_consumed_bytes(MpegEncContext *s, int buf_size){
|
||||
int pos= get_bits_count(&s->gb)>>3;
|
||||
if(pos==0) pos=1; //avoid infinite loops (i doubt that is needed but ...)
|
||||
if(pos+10>buf_size) pos=buf_size; // oops ;)
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
static int h261_decode_frame(AVCodecContext *avctx,
|
||||
void *data, int *data_size,
|
||||
const uint8_t *buf, int buf_size)
|
||||
{
|
||||
H261Context *h= avctx->priv_data;
|
||||
MpegEncContext *s = &h->s;
|
||||
int ret;
|
||||
AVFrame *pict = data;
|
||||
|
||||
#ifdef DEBUG
|
||||
av_log(avctx, AV_LOG_DEBUG, "*****frame %d size=%d\n", avctx->frame_number, buf_size);
|
||||
av_log(avctx, AV_LOG_DEBUG, "bytes=%x %x %x %x\n", buf[0], buf[1], buf[2], buf[3]);
|
||||
#endif
|
||||
s->flags= avctx->flags;
|
||||
s->flags2= avctx->flags2;
|
||||
|
||||
h->gob_start_code_skipped=0;
|
||||
|
||||
retry:
|
||||
|
||||
init_get_bits(&s->gb, buf, buf_size*8);
|
||||
|
||||
if(!s->context_initialized){
|
||||
if (MPV_common_init(s) < 0) //we need the idct permutaton for reading a custom matrix
|
||||
return -1;
|
||||
}
|
||||
|
||||
//we need to set current_picture_ptr before reading the header, otherwise we cannot store anyting im there
|
||||
if(s->current_picture_ptr==NULL || s->current_picture_ptr->data[0]){
|
||||
int i= ff_find_unused_picture(s, 0);
|
||||
s->current_picture_ptr= &s->picture[i];
|
||||
}
|
||||
|
||||
ret = h261_decode_picture_header(h);
|
||||
|
||||
/* skip if the header was thrashed */
|
||||
if (ret < 0){
|
||||
av_log(s->avctx, AV_LOG_ERROR, "header damaged\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (s->width != avctx->coded_width || s->height != avctx->coded_height){
|
||||
ParseContext pc= s->parse_context; //FIXME move this demuxing hack to libavformat
|
||||
s->parse_context.buffer=0;
|
||||
MPV_common_end(s);
|
||||
s->parse_context= pc;
|
||||
}
|
||||
if (!s->context_initialized) {
|
||||
avcodec_set_dimensions(avctx, s->width, s->height);
|
||||
|
||||
goto retry;
|
||||
}
|
||||
|
||||
// for hurry_up==5
|
||||
s->current_picture.pict_type= s->pict_type;
|
||||
s->current_picture.key_frame= s->pict_type == FF_I_TYPE;
|
||||
|
||||
/* skip everything if we are in a hurry>=5 */
|
||||
if(avctx->hurry_up>=5) return get_consumed_bytes(s, buf_size);
|
||||
if( (avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type==FF_B_TYPE)
|
||||
||(avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type!=FF_I_TYPE)
|
||||
|| avctx->skip_frame >= AVDISCARD_ALL)
|
||||
return get_consumed_bytes(s, buf_size);
|
||||
|
||||
if(MPV_frame_start(s, avctx) < 0)
|
||||
return -1;
|
||||
|
||||
ff_er_frame_start(s);
|
||||
|
||||
/* decode each macroblock */
|
||||
s->mb_x=0;
|
||||
s->mb_y=0;
|
||||
|
||||
while(h->gob_number < (s->mb_height==18 ? 12 : 5)){
|
||||
if(ff_h261_resync(h)<0)
|
||||
break;
|
||||
h261_decode_gob(h);
|
||||
}
|
||||
MPV_frame_end(s);
|
||||
|
||||
assert(s->current_picture.pict_type == s->current_picture_ptr->pict_type);
|
||||
assert(s->current_picture.pict_type == s->pict_type);
|
||||
*pict= *(AVFrame*)s->current_picture_ptr;
|
||||
ff_print_debug_info(s, pict);
|
||||
|
||||
*data_size = sizeof(AVFrame);
|
||||
|
||||
return get_consumed_bytes(s, buf_size);
|
||||
}
|
||||
|
||||
static av_cold int h261_decode_end(AVCodecContext *avctx)
|
||||
{
|
||||
H261Context *h= avctx->priv_data;
|
||||
MpegEncContext *s = &h->s;
|
||||
|
||||
MPV_common_end(s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
AVCodec h261_decoder = {
|
||||
"h261",
|
||||
CODEC_TYPE_VIDEO,
|
||||
CODEC_ID_H261,
|
||||
sizeof(H261Context),
|
||||
h261_decode_init,
|
||||
NULL,
|
||||
h261_decode_end,
|
||||
h261_decode_frame,
|
||||
CODEC_CAP_DR1,
|
||||
.long_name = NULL_IF_CONFIG_SMALL("H.261"),
|
||||
};
|
335
src/add-ons/media/plugins/avcodec/libavcodec/h261enc.c
Normal file
335
src/add-ons/media/plugins/avcodec/libavcodec/h261enc.c
Normal file
@ -0,0 +1,335 @@
|
||||
/*
|
||||
* H261 encoder
|
||||
* Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
|
||||
* Copyright (c) 2004 Maarten Daniels
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg 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,
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file h261enc.c
|
||||
* H.261 encoder.
|
||||
*/
|
||||
|
||||
#include "dsputil.h"
|
||||
#include "avcodec.h"
|
||||
#include "mpegvideo.h"
|
||||
#include "h261.h"
|
||||
#include "h261data.h"
|
||||
|
||||
extern uint8_t ff_h261_rl_table_store[2][2*MAX_RUN + MAX_LEVEL + 3];
|
||||
|
||||
static void h261_encode_block(H261Context * h, DCTELEM * block,
|
||||
int n);
|
||||
|
||||
int ff_h261_get_picture_format(int width, int height){
|
||||
// QCIF
|
||||
if (width == 176 && height == 144)
|
||||
return 0;
|
||||
// CIF
|
||||
else if (width == 352 && height == 288)
|
||||
return 1;
|
||||
// ERROR
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
void ff_h261_encode_picture_header(MpegEncContext * s, int picture_number){
|
||||
H261Context * h = (H261Context *) s;
|
||||
int format, temp_ref;
|
||||
|
||||
align_put_bits(&s->pb);
|
||||
|
||||
/* Update the pointer to last GOB */
|
||||
s->ptr_lastgob = pbBufPtr(&s->pb);
|
||||
|
||||
put_bits(&s->pb, 20, 0x10); /* PSC */
|
||||
|
||||
temp_ref= s->picture_number * (int64_t)30000 * s->avctx->time_base.num /
|
||||
(1001 * (int64_t)s->avctx->time_base.den); //FIXME maybe this should use a timestamp
|
||||
put_sbits(&s->pb, 5, temp_ref); /* TemporalReference */
|
||||
|
||||
put_bits(&s->pb, 1, 0); /* split screen off */
|
||||
put_bits(&s->pb, 1, 0); /* camera off */
|
||||
put_bits(&s->pb, 1, 0); /* freeze picture release off */
|
||||
|
||||
format = ff_h261_get_picture_format(s->width, s->height);
|
||||
|
||||
put_bits(&s->pb, 1, format); /* 0 == QCIF, 1 == CIF */
|
||||
|
||||
put_bits(&s->pb, 1, 0); /* still image mode */
|
||||
put_bits(&s->pb, 1, 0); /* reserved */
|
||||
|
||||
put_bits(&s->pb, 1, 0); /* no PEI */
|
||||
if(format == 0)
|
||||
h->gob_number = -1;
|
||||
else
|
||||
h->gob_number = 0;
|
||||
h->current_mba = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes a group of blocks header.
|
||||
*/
|
||||
static void h261_encode_gob_header(MpegEncContext * s, int mb_line){
|
||||
H261Context * h = (H261Context *)s;
|
||||
if(ff_h261_get_picture_format(s->width, s->height) == 0){
|
||||
h->gob_number+=2; // QCIF
|
||||
}
|
||||
else{
|
||||
h->gob_number++; // CIF
|
||||
}
|
||||
put_bits(&s->pb, 16, 1); /* GBSC */
|
||||
put_bits(&s->pb, 4, h->gob_number); /* GN */
|
||||
put_bits(&s->pb, 5, s->qscale); /* GQUANT */
|
||||
put_bits(&s->pb, 1, 0); /* no GEI */
|
||||
h->current_mba = 0;
|
||||
h->previous_mba = 0;
|
||||
h->current_mv_x=0;
|
||||
h->current_mv_y=0;
|
||||
}
|
||||
|
||||
void ff_h261_reorder_mb_index(MpegEncContext* s){
|
||||
int index= s->mb_x + s->mb_y*s->mb_width;
|
||||
|
||||
if(index % 33 == 0)
|
||||
h261_encode_gob_header(s,0);
|
||||
|
||||
/* for CIF the GOB's are fragmented in the middle of a scanline
|
||||
that's why we need to adjust the x and y index of the macroblocks */
|
||||
if(ff_h261_get_picture_format(s->width,s->height) == 1){ // CIF
|
||||
s->mb_x = index % 11 ; index /= 11;
|
||||
s->mb_y = index % 3 ; index /= 3;
|
||||
s->mb_x+= 11*(index % 2); index /= 2;
|
||||
s->mb_y+= 3*index;
|
||||
|
||||
ff_init_block_index(s);
|
||||
ff_update_block_index(s);
|
||||
}
|
||||
}
|
||||
|
||||
static void h261_encode_motion(H261Context * h, int val){
|
||||
MpegEncContext * const s = &h->s;
|
||||
int sign, code;
|
||||
if(val==0){
|
||||
code = 0;
|
||||
put_bits(&s->pb,h261_mv_tab[code][1],h261_mv_tab[code][0]);
|
||||
}
|
||||
else{
|
||||
if(val > 15)
|
||||
val -=32;
|
||||
if(val < -16)
|
||||
val+=32;
|
||||
sign = val < 0;
|
||||
code = sign ? -val : val;
|
||||
put_bits(&s->pb,h261_mv_tab[code][1],h261_mv_tab[code][0]);
|
||||
put_bits(&s->pb,1,sign);
|
||||
}
|
||||
}
|
||||
|
||||
static inline int get_cbp(MpegEncContext * s,
|
||||
DCTELEM block[6][64])
|
||||
{
|
||||
int i, cbp;
|
||||
cbp= 0;
|
||||
for (i = 0; i < 6; i++) {
|
||||
if (s->block_last_index[i] >= 0)
|
||||
cbp |= 1 << (5 - i);
|
||||
}
|
||||
return cbp;
|
||||
}
|
||||
void ff_h261_encode_mb(MpegEncContext * s,
|
||||
DCTELEM block[6][64],
|
||||
int motion_x, int motion_y)
|
||||
{
|
||||
H261Context * h = (H261Context *)s;
|
||||
int mvd, mv_diff_x, mv_diff_y, i, cbp;
|
||||
cbp = 63; // avoid warning
|
||||
mvd = 0;
|
||||
|
||||
h->current_mba++;
|
||||
h->mtype = 0;
|
||||
|
||||
if (!s->mb_intra){
|
||||
/* compute cbp */
|
||||
cbp= get_cbp(s, block);
|
||||
|
||||
/* mvd indicates if this block is motion compensated */
|
||||
mvd = motion_x | motion_y;
|
||||
|
||||
if((cbp | mvd | s->dquant ) == 0) {
|
||||
/* skip macroblock */
|
||||
s->skip_count++;
|
||||
h->current_mv_x=0;
|
||||
h->current_mv_y=0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* MB is not skipped, encode MBA */
|
||||
put_bits(&s->pb, h261_mba_bits[(h->current_mba-h->previous_mba)-1], h261_mba_code[(h->current_mba-h->previous_mba)-1]);
|
||||
|
||||
/* calculate MTYPE */
|
||||
if(!s->mb_intra){
|
||||
h->mtype++;
|
||||
|
||||
if(mvd || s->loop_filter)
|
||||
h->mtype+=3;
|
||||
if(s->loop_filter)
|
||||
h->mtype+=3;
|
||||
if(cbp || s->dquant)
|
||||
h->mtype++;
|
||||
assert(h->mtype > 1);
|
||||
}
|
||||
|
||||
if(s->dquant)
|
||||
h->mtype++;
|
||||
|
||||
put_bits(&s->pb, h261_mtype_bits[h->mtype], h261_mtype_code[h->mtype]);
|
||||
|
||||
h->mtype = h261_mtype_map[h->mtype];
|
||||
|
||||
if(IS_QUANT(h->mtype)){
|
||||
ff_set_qscale(s,s->qscale+s->dquant);
|
||||
put_bits(&s->pb, 5, s->qscale);
|
||||
}
|
||||
|
||||
if(IS_16X16(h->mtype)){
|
||||
mv_diff_x = (motion_x >> 1) - h->current_mv_x;
|
||||
mv_diff_y = (motion_y >> 1) - h->current_mv_y;
|
||||
h->current_mv_x = (motion_x >> 1);
|
||||
h->current_mv_y = (motion_y >> 1);
|
||||
h261_encode_motion(h,mv_diff_x);
|
||||
h261_encode_motion(h,mv_diff_y);
|
||||
}
|
||||
|
||||
h->previous_mba = h->current_mba;
|
||||
|
||||
if(HAS_CBP(h->mtype)){
|
||||
assert(cbp>0);
|
||||
put_bits(&s->pb,h261_cbp_tab[cbp-1][1],h261_cbp_tab[cbp-1][0]);
|
||||
}
|
||||
for(i=0; i<6; i++) {
|
||||
/* encode each block */
|
||||
h261_encode_block(h, block[i], i);
|
||||
}
|
||||
|
||||
if ( ( h->current_mba == 11 ) || ( h->current_mba == 22 ) || ( h->current_mba == 33 ) || ( !IS_16X16 ( h->mtype ) )){
|
||||
h->current_mv_x=0;
|
||||
h->current_mv_y=0;
|
||||
}
|
||||
}
|
||||
|
||||
void ff_h261_encode_init(MpegEncContext *s){
|
||||
static int done = 0;
|
||||
|
||||
if (!done) {
|
||||
done = 1;
|
||||
init_rl(&h261_rl_tcoeff, ff_h261_rl_table_store);
|
||||
}
|
||||
|
||||
s->min_qcoeff= -127;
|
||||
s->max_qcoeff= 127;
|
||||
s->y_dc_scale_table=
|
||||
s->c_dc_scale_table= ff_mpeg1_dc_scale_table;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* encodes a 8x8 block.
|
||||
* @param block the 8x8 block
|
||||
* @param n block index (0-3 are luma, 4-5 are chroma)
|
||||
*/
|
||||
static void h261_encode_block(H261Context * h, DCTELEM * block, int n){
|
||||
MpegEncContext * const s = &h->s;
|
||||
int level, run, last, i, j, last_index, last_non_zero, sign, slevel, code;
|
||||
RLTable *rl;
|
||||
|
||||
rl = &h261_rl_tcoeff;
|
||||
if (s->mb_intra) {
|
||||
/* DC coef */
|
||||
level = block[0];
|
||||
/* 255 cannot be represented, so we clamp */
|
||||
if (level > 254) {
|
||||
level = 254;
|
||||
block[0] = 254;
|
||||
}
|
||||
/* 0 cannot be represented also */
|
||||
else if (level < 1) {
|
||||
level = 1;
|
||||
block[0] = 1;
|
||||
}
|
||||
if (level == 128)
|
||||
put_bits(&s->pb, 8, 0xff);
|
||||
else
|
||||
put_bits(&s->pb, 8, level);
|
||||
i = 1;
|
||||
} else if((block[0]==1 || block[0] == -1) && (s->block_last_index[n] > -1)){
|
||||
//special case
|
||||
put_bits(&s->pb,2,block[0]>0 ? 2 : 3 );
|
||||
i = 1;
|
||||
} else {
|
||||
i = 0;
|
||||
}
|
||||
|
||||
/* AC coefs */
|
||||
last_index = s->block_last_index[n];
|
||||
last_non_zero = i - 1;
|
||||
for (; i <= last_index; i++) {
|
||||
j = s->intra_scantable.permutated[i];
|
||||
level = block[j];
|
||||
if (level) {
|
||||
run = i - last_non_zero - 1;
|
||||
last = (i == last_index);
|
||||
sign = 0;
|
||||
slevel = level;
|
||||
if (level < 0) {
|
||||
sign = 1;
|
||||
level = -level;
|
||||
}
|
||||
code = get_rl_index(rl, 0 /*no last in H.261, EOB is used*/, run, level);
|
||||
if(run==0 && level < 16)
|
||||
code+=1;
|
||||
put_bits(&s->pb, rl->table_vlc[code][1], rl->table_vlc[code][0]);
|
||||
if (code == rl->n) {
|
||||
put_bits(&s->pb, 6, run);
|
||||
assert(slevel != 0);
|
||||
assert(level <= 127);
|
||||
put_sbits(&s->pb, 8, slevel);
|
||||
} else {
|
||||
put_bits(&s->pb, 1, sign);
|
||||
}
|
||||
last_non_zero = i;
|
||||
}
|
||||
}
|
||||
if(last_index > -1){
|
||||
put_bits(&s->pb, rl->table_vlc[0][1], rl->table_vlc[0][0]);// END OF BLOCK
|
||||
}
|
||||
}
|
||||
|
||||
AVCodec h261_encoder = {
|
||||
"h261",
|
||||
CODEC_TYPE_VIDEO,
|
||||
CODEC_ID_H261,
|
||||
sizeof(H261Context),
|
||||
MPV_encode_init,
|
||||
MPV_encode_picture,
|
||||
MPV_encode_end,
|
||||
.pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE},
|
||||
.long_name= NULL_IF_CONFIG_SMALL("H.261"),
|
||||
};
|
||||
|
File diff suppressed because it is too large
Load Diff
46
src/add-ons/media/plugins/avcodec/libavcodec/h263.h
Normal file
46
src/add-ons/media/plugins/avcodec/libavcodec/h263.h
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* H263/MPEG4 backend for ffmpeg encoder and decoder
|
||||
* copyright (c) 2007 Aurelien Jacobs <aurel@gnuage.org>
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg 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,
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef FFMPEG_H263_H
|
||||
#define FFMPEG_H263_H
|
||||
|
||||
#include "config.h"
|
||||
#include "msmpeg4.h"
|
||||
|
||||
#define ENABLE_ANY_H263_DECODER (ENABLE_H263_DECODER || \
|
||||
ENABLE_H263I_DECODER || \
|
||||
ENABLE_FLV_DECODER || \
|
||||
ENABLE_RV10_DECODER || \
|
||||
ENABLE_RV20_DECODER || \
|
||||
ENABLE_MPEG4_DECODER || \
|
||||
ENABLE_MSMPEG4_DECODER || \
|
||||
ENABLE_WMV_DECODER)
|
||||
#define ENABLE_ANY_H263_ENCODER (ENABLE_H263_ENCODER || \
|
||||
ENABLE_H263P_ENCODER || \
|
||||
ENABLE_FLV_ENCODER || \
|
||||
ENABLE_RV10_ENCODER || \
|
||||
ENABLE_RV20_ENCODER || \
|
||||
ENABLE_MPEG4_ENCODER || \
|
||||
ENABLE_MSMPEG4_ENCODER || \
|
||||
ENABLE_WMV_ENCODER)
|
||||
#define ENABLE_ANY_H263 (ENABLE_ANY_H263_DECODER || ENABLE_ANY_H263_ENCODER)
|
||||
|
||||
#endif /* FFMPEG_H263_H */
|
91
src/add-ons/media/plugins/avcodec/libavcodec/h263_parser.c
Normal file
91
src/add-ons/media/plugins/avcodec/libavcodec/h263_parser.c
Normal file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* H.263 parser
|
||||
* Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg 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,
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file h263_parser.c
|
||||
* H.263 parser
|
||||
*/
|
||||
|
||||
#include "parser.h"
|
||||
|
||||
int ff_h263_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size){
|
||||
int vop_found, i;
|
||||
uint32_t state;
|
||||
|
||||
vop_found= pc->frame_start_found;
|
||||
state= pc->state;
|
||||
|
||||
i=0;
|
||||
if(!vop_found){
|
||||
for(i=0; i<buf_size; i++){
|
||||
state= (state<<8) | buf[i];
|
||||
if(state>>(32-22) == 0x20){
|
||||
i++;
|
||||
vop_found=1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(vop_found){
|
||||
for(; i<buf_size; i++){
|
||||
state= (state<<8) | buf[i];
|
||||
if(state>>(32-22) == 0x20){
|
||||
pc->frame_start_found=0;
|
||||
pc->state=-1;
|
||||
return i-3;
|
||||
}
|
||||
}
|
||||
}
|
||||
pc->frame_start_found= vop_found;
|
||||
pc->state= state;
|
||||
|
||||
return END_NOT_FOUND;
|
||||
}
|
||||
|
||||
static int h263_parse(AVCodecParserContext *s,
|
||||
AVCodecContext *avctx,
|
||||
const uint8_t **poutbuf, int *poutbuf_size,
|
||||
const uint8_t *buf, int buf_size)
|
||||
{
|
||||
ParseContext *pc = s->priv_data;
|
||||
int next;
|
||||
|
||||
next= ff_h263_find_frame_end(pc, buf, buf_size);
|
||||
|
||||
if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
|
||||
*poutbuf = NULL;
|
||||
*poutbuf_size = 0;
|
||||
return buf_size;
|
||||
}
|
||||
|
||||
*poutbuf = buf;
|
||||
*poutbuf_size = buf_size;
|
||||
return next;
|
||||
}
|
||||
|
||||
AVCodecParser h263_parser = {
|
||||
{ CODEC_ID_H263 },
|
||||
sizeof(ParseContext),
|
||||
NULL,
|
||||
h263_parse,
|
||||
ff_parse_close,
|
||||
};
|
29
src/add-ons/media/plugins/avcodec/libavcodec/h263_parser.h
Normal file
29
src/add-ons/media/plugins/avcodec/libavcodec/h263_parser.h
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* H.263 parser
|
||||
* Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg 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,
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef FFMPEG_H263_PARSER_H
|
||||
#define FFMPEG_H263_PARSER_H
|
||||
|
||||
#include "parser.h"
|
||||
|
||||
int ff_h263_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size);
|
||||
|
||||
#endif /* FFMPEG_H263_PARSER_H */
|
@ -1,8 +1,36 @@
|
||||
/*
|
||||
* copyright (c) 2000,2001 Fabrice Bellard
|
||||
* H263+ support
|
||||
* copyright (c) 2001 Juan J. Sierralta P.
|
||||
* copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg 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,
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file h263data.h
|
||||
* H.263 tables.
|
||||
*/
|
||||
|
||||
#ifndef FFMPEG_H263DATA_H
|
||||
#define FFMPEG_H263DATA_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "mpegvideo.h"
|
||||
|
||||
/* intra MCBPC, mb_type = (intra), then (intraq) */
|
||||
const uint8_t intra_MCBPC_code[9] = { 1, 1, 2, 3, 1, 1, 2, 3, 1 };
|
||||
@ -10,16 +38,16 @@ const uint8_t intra_MCBPC_bits[9] = { 1, 3, 3, 3, 4, 6, 6, 6, 9 };
|
||||
|
||||
/* inter MCBPC, mb_type = (inter), (intra), (interq), (intraq), (inter4v) */
|
||||
/* Changed the tables for interq and inter4v+q, following the standard ** Juanjo ** */
|
||||
const uint8_t inter_MCBPC_code[28] = {
|
||||
1, 3, 2, 5,
|
||||
3, 4, 3, 3,
|
||||
const uint8_t inter_MCBPC_code[28] = {
|
||||
1, 3, 2, 5,
|
||||
3, 4, 3, 3,
|
||||
3, 7, 6, 5,
|
||||
4, 4, 3, 2,
|
||||
2, 5, 4, 5,
|
||||
1, 0, 0, 0, /* Stuffing */
|
||||
2, 12, 14, 15,
|
||||
};
|
||||
const uint8_t inter_MCBPC_bits[28] = {
|
||||
const uint8_t inter_MCBPC_bits[28] = {
|
||||
1, 4, 4, 6, /* inter */
|
||||
5, 8, 8, 7, /* intra */
|
||||
3, 7, 7, 9, /* interQ */
|
||||
@ -30,9 +58,9 @@ const uint8_t inter_MCBPC_bits[28] = {
|
||||
};
|
||||
|
||||
static const uint8_t h263_mbtype_b_tab[15][2] = {
|
||||
{1, 1},
|
||||
{3, 3},
|
||||
{1, 5},
|
||||
{1, 1},
|
||||
{3, 3},
|
||||
{1, 5},
|
||||
{4, 4},
|
||||
{5, 4},
|
||||
{6, 6},
|
||||
@ -65,7 +93,7 @@ static const int h263_mb_type_b_map[15]= {
|
||||
MB_TYPE_INTRA4x4 | MB_TYPE_CBP | MB_TYPE_QUANT,
|
||||
};
|
||||
|
||||
const uint8_t cbpc_b_tab[4][2] = {
|
||||
static const uint8_t cbpc_b_tab[4][2] = {
|
||||
{0, 1},
|
||||
{2, 2},
|
||||
{7, 3},
|
||||
@ -157,64 +185,64 @@ static RLTable rl_inter = {
|
||||
inter_level,
|
||||
};
|
||||
|
||||
const uint16_t intra_vlc_aic[103][2] = {
|
||||
{ 0x2, 2 }, { 0x6, 3 }, { 0xe, 4 }, { 0xc, 5 },
|
||||
{ 0xd, 5 }, { 0x10, 6 }, { 0x11, 6 }, { 0x12, 6 },
|
||||
{ 0x16, 7 }, { 0x1b, 8 }, { 0x20, 9 }, { 0x21, 9 },
|
||||
{ 0x1a, 9 }, { 0x1b, 9 }, { 0x1c, 9 }, { 0x1d, 9 },
|
||||
{ 0x1e, 9 }, { 0x1f, 9 }, { 0x23, 11 }, { 0x22, 11 },
|
||||
{ 0x57, 12 }, { 0x56, 12 }, { 0x55, 12 }, { 0x54, 12 },
|
||||
{ 0x53, 12 }, { 0xf, 4 }, { 0x14, 6 }, { 0x14, 7 },
|
||||
{ 0x1e, 8 }, { 0xf, 10 }, { 0x21, 11 }, { 0x50, 12 },
|
||||
{ 0xb, 5 }, { 0x15, 7 }, { 0xe, 10 }, { 0x9, 10 },
|
||||
{ 0x15, 6 }, { 0x1d, 8 }, { 0xd, 10 }, { 0x51, 12 },
|
||||
{ 0x13, 6 }, { 0x23, 9 }, { 0x7, 11 }, { 0x17, 7 },
|
||||
{ 0x22, 9 }, { 0x52, 12 }, { 0x1c, 8 }, { 0xc, 10 },
|
||||
{ 0x1f, 8 }, { 0xb, 10 }, { 0x25, 9 }, { 0xa, 10 },
|
||||
{ 0x24, 9 }, { 0x6, 11 }, { 0x21, 10 }, { 0x20, 10 },
|
||||
{ 0x8, 10 }, { 0x20, 11 }, { 0x7, 4 }, { 0xc, 6 },
|
||||
{ 0x10, 7 }, { 0x13, 8 }, { 0x11, 9 }, { 0x12, 9 },
|
||||
{ 0x4, 10 }, { 0x27, 11 }, { 0x26, 11 }, { 0x5f, 12 },
|
||||
{ 0xf, 6 }, { 0x13, 9 }, { 0x5, 10 }, { 0x25, 11 },
|
||||
{ 0xe, 6 }, { 0x14, 9 }, { 0x24, 11 }, { 0xd, 6 },
|
||||
{ 0x6, 10 }, { 0x5e, 12 }, { 0x11, 7 }, { 0x7, 10 },
|
||||
{ 0x13, 7 }, { 0x5d, 12 }, { 0x12, 7 }, { 0x5c, 12 },
|
||||
{ 0x14, 8 }, { 0x5b, 12 }, { 0x15, 8 }, { 0x1a, 8 },
|
||||
{ 0x19, 8 }, { 0x18, 8 }, { 0x17, 8 }, { 0x16, 8 },
|
||||
{ 0x19, 9 }, { 0x15, 9 }, { 0x16, 9 }, { 0x18, 9 },
|
||||
{ 0x17, 9 }, { 0x4, 11 }, { 0x5, 11 }, { 0x58, 12 },
|
||||
static const uint16_t intra_vlc_aic[103][2] = {
|
||||
{ 0x2, 2 }, { 0x6, 3 }, { 0xe, 4 }, { 0xc, 5 },
|
||||
{ 0xd, 5 }, { 0x10, 6 }, { 0x11, 6 }, { 0x12, 6 },
|
||||
{ 0x16, 7 }, { 0x1b, 8 }, { 0x20, 9 }, { 0x21, 9 },
|
||||
{ 0x1a, 9 }, { 0x1b, 9 }, { 0x1c, 9 }, { 0x1d, 9 },
|
||||
{ 0x1e, 9 }, { 0x1f, 9 }, { 0x23, 11 }, { 0x22, 11 },
|
||||
{ 0x57, 12 }, { 0x56, 12 }, { 0x55, 12 }, { 0x54, 12 },
|
||||
{ 0x53, 12 }, { 0xf, 4 }, { 0x14, 6 }, { 0x14, 7 },
|
||||
{ 0x1e, 8 }, { 0xf, 10 }, { 0x21, 11 }, { 0x50, 12 },
|
||||
{ 0xb, 5 }, { 0x15, 7 }, { 0xe, 10 }, { 0x9, 10 },
|
||||
{ 0x15, 6 }, { 0x1d, 8 }, { 0xd, 10 }, { 0x51, 12 },
|
||||
{ 0x13, 6 }, { 0x23, 9 }, { 0x7, 11 }, { 0x17, 7 },
|
||||
{ 0x22, 9 }, { 0x52, 12 }, { 0x1c, 8 }, { 0xc, 10 },
|
||||
{ 0x1f, 8 }, { 0xb, 10 }, { 0x25, 9 }, { 0xa, 10 },
|
||||
{ 0x24, 9 }, { 0x6, 11 }, { 0x21, 10 }, { 0x20, 10 },
|
||||
{ 0x8, 10 }, { 0x20, 11 }, { 0x7, 4 }, { 0xc, 6 },
|
||||
{ 0x10, 7 }, { 0x13, 8 }, { 0x11, 9 }, { 0x12, 9 },
|
||||
{ 0x4, 10 }, { 0x27, 11 }, { 0x26, 11 }, { 0x5f, 12 },
|
||||
{ 0xf, 6 }, { 0x13, 9 }, { 0x5, 10 }, { 0x25, 11 },
|
||||
{ 0xe, 6 }, { 0x14, 9 }, { 0x24, 11 }, { 0xd, 6 },
|
||||
{ 0x6, 10 }, { 0x5e, 12 }, { 0x11, 7 }, { 0x7, 10 },
|
||||
{ 0x13, 7 }, { 0x5d, 12 }, { 0x12, 7 }, { 0x5c, 12 },
|
||||
{ 0x14, 8 }, { 0x5b, 12 }, { 0x15, 8 }, { 0x1a, 8 },
|
||||
{ 0x19, 8 }, { 0x18, 8 }, { 0x17, 8 }, { 0x16, 8 },
|
||||
{ 0x19, 9 }, { 0x15, 9 }, { 0x16, 9 }, { 0x18, 9 },
|
||||
{ 0x17, 9 }, { 0x4, 11 }, { 0x5, 11 }, { 0x58, 12 },
|
||||
{ 0x59, 12 }, { 0x5a, 12 }, { 0x3, 7 },
|
||||
};
|
||||
|
||||
const int8_t intra_run_aic[102] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 1, 1, 1, 1, 1, 1, 1,
|
||||
2, 2, 2, 2, 3, 3, 3, 3,
|
||||
4, 4, 4, 5, 5, 5, 6, 6,
|
||||
7, 7, 8, 8, 9, 9, 10, 11,
|
||||
12, 13, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 1, 1, 1, 1,
|
||||
2, 2, 2, 3, 3, 3, 4, 4,
|
||||
5, 5, 6, 6, 7, 7, 8, 9,
|
||||
10, 11, 12, 13, 14, 15, 16, 17,
|
||||
18, 19, 20, 21, 22, 23,
|
||||
static const int8_t intra_run_aic[102] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 1, 1, 1, 1, 1, 1, 1,
|
||||
2, 2, 2, 2, 3, 3, 3, 3,
|
||||
4, 4, 4, 5, 5, 5, 6, 6,
|
||||
7, 7, 8, 8, 9, 9, 10, 11,
|
||||
12, 13, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 1, 1, 1, 1,
|
||||
2, 2, 2, 3, 3, 3, 4, 4,
|
||||
5, 5, 6, 6, 7, 7, 8, 9,
|
||||
10, 11, 12, 13, 14, 15, 16, 17,
|
||||
18, 19, 20, 21, 22, 23,
|
||||
};
|
||||
|
||||
const int8_t intra_level_aic[102] = {
|
||||
1, 2, 3, 4, 5, 6, 7, 8,
|
||||
9, 10, 11, 12, 13, 14, 15, 16,
|
||||
17, 18, 19, 20, 21, 22, 23, 24,
|
||||
25, 1, 2, 3, 4, 5, 6, 7,
|
||||
1, 2, 3, 4, 1, 2, 3, 4,
|
||||
1, 2, 3, 1, 2, 3, 1, 2,
|
||||
1, 2, 1, 2, 1, 2, 1, 1,
|
||||
1, 1, 1, 2, 3, 4, 5, 6,
|
||||
7, 8, 9, 10, 1, 2, 3, 4,
|
||||
1, 2, 3, 1, 2, 3, 1, 2,
|
||||
1, 2, 1, 2, 1, 2, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
static const int8_t intra_level_aic[102] = {
|
||||
1, 2, 3, 4, 5, 6, 7, 8,
|
||||
9, 10, 11, 12, 13, 14, 15, 16,
|
||||
17, 18, 19, 20, 21, 22, 23, 24,
|
||||
25, 1, 2, 3, 4, 5, 6, 7,
|
||||
1, 2, 3, 4, 1, 2, 3, 4,
|
||||
1, 2, 3, 1, 2, 3, 1, 2,
|
||||
1, 2, 1, 2, 1, 2, 1, 1,
|
||||
1, 1, 1, 2, 3, 4, 5, 6,
|
||||
7, 8, 9, 10, 1, 2, 3, 4,
|
||||
1, 2, 3, 1, 2, 3, 1, 2,
|
||||
1, 2, 1, 2, 1, 2, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1,
|
||||
};
|
||||
|
||||
@ -227,18 +255,18 @@ static RLTable rl_intra_aic = {
|
||||
};
|
||||
|
||||
static const uint8_t wrong_run[102] = {
|
||||
1, 2, 3, 5, 4, 10, 9, 8,
|
||||
11, 15, 17, 16, 23, 22, 21, 20,
|
||||
19, 18, 25, 24, 27, 26, 11, 7,
|
||||
6, 1, 2, 13, 2, 2, 2, 2,
|
||||
6, 12, 3, 9, 1, 3, 4, 3,
|
||||
7, 4, 1, 1, 5, 5, 14, 6,
|
||||
1, 7, 1, 8, 1, 1, 1, 1,
|
||||
10, 1, 1, 5, 9, 17, 25, 24,
|
||||
29, 33, 32, 41, 2, 23, 28, 31,
|
||||
3, 22, 30, 4, 27, 40, 8, 26,
|
||||
6, 39, 7, 38, 16, 37, 15, 10,
|
||||
11, 12, 13, 14, 1, 21, 20, 18,
|
||||
1, 2, 3, 5, 4, 10, 9, 8,
|
||||
11, 15, 17, 16, 23, 22, 21, 20,
|
||||
19, 18, 25, 24, 27, 26, 11, 7,
|
||||
6, 1, 2, 13, 2, 2, 2, 2,
|
||||
6, 12, 3, 9, 1, 3, 4, 3,
|
||||
7, 4, 1, 1, 5, 5, 14, 6,
|
||||
1, 7, 1, 8, 1, 1, 1, 1,
|
||||
10, 1, 1, 5, 9, 17, 25, 24,
|
||||
29, 33, 32, 41, 2, 23, 28, 31,
|
||||
3, 22, 30, 4, 27, 40, 8, 26,
|
||||
6, 39, 7, 38, 16, 37, 15, 10,
|
||||
11, 12, 13, 14, 1, 21, 20, 18,
|
||||
19, 2, 1, 34, 35, 36
|
||||
};
|
||||
|
||||
@ -251,7 +279,7 @@ static const uint16_t h263_format[8][2] = {
|
||||
{ 1408, 1152 },
|
||||
};
|
||||
|
||||
uint8_t ff_aic_dc_scale_table[32]={
|
||||
const uint8_t ff_aic_dc_scale_table[32]={
|
||||
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
|
||||
0, 2, 4, 6, 8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58,60,62
|
||||
};
|
||||
@ -262,7 +290,7 @@ static const uint8_t modified_quant_tab[2][32]={
|
||||
0, 3, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9,10,11,12,13,14,15,16,17,18,18,19,20,21,22,23,24,25,26,27,28
|
||||
},{
|
||||
0, 2, 3, 4, 5, 6, 7, 8, 9,10,11,13,14,15,16,17,18,19,20,21,22,24,25,26,27,28,29,30,31,31,31,26
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const uint8_t ff_h263_chroma_qscale_table[32]={
|
||||
@ -274,8 +302,8 @@ const uint16_t ff_mba_max[6]={
|
||||
47, 98, 395,1583,6335,9215
|
||||
};
|
||||
|
||||
const uint8_t ff_mba_length[6]={
|
||||
6, 7, 9, 11, 13, 14
|
||||
const uint8_t ff_mba_length[7]={
|
||||
6, 7, 9, 11, 13, 14, 14
|
||||
};
|
||||
|
||||
const uint8_t ff_h263_loop_filter_strength[32]={
|
||||
@ -283,3 +311,4 @@ const uint8_t ff_h263_loop_filter_strength[32]={
|
||||
0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9,10,10,10,11,11,11,12,12,12
|
||||
};
|
||||
|
||||
#endif /* FFMPEG_H263DATA_H */
|
||||
|
@ -3,47 +3,52 @@
|
||||
* Copyright (c) 2001 Fabrice Bellard.
|
||||
* Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg 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 of the License, or (at your option) any later version.
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* FFmpeg 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 this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @file h263dec.c
|
||||
* H.263 decoder.
|
||||
*/
|
||||
|
||||
|
||||
#include "avcodec.h"
|
||||
#include "dsputil.h"
|
||||
#include "mpegvideo.h"
|
||||
#include "h263_parser.h"
|
||||
#include "mpeg4video_parser.h"
|
||||
#include "msmpeg4.h"
|
||||
|
||||
//#define DEBUG
|
||||
//#define PRINT_FRAME_TIME
|
||||
|
||||
int ff_h263_decode_init(AVCodecContext *avctx)
|
||||
av_cold int ff_h263_decode_init(AVCodecContext *avctx)
|
||||
{
|
||||
MpegEncContext *s = avctx->priv_data;
|
||||
|
||||
s->avctx = avctx;
|
||||
s->out_format = FMT_H263;
|
||||
|
||||
s->width = avctx->width;
|
||||
s->height = avctx->height;
|
||||
s->width = avctx->coded_width;
|
||||
s->height = avctx->coded_height;
|
||||
s->workaround_bugs= avctx->workaround_bugs;
|
||||
|
||||
// set defaults
|
||||
MPV_decode_defaults(s);
|
||||
s->quant_precision=5;
|
||||
s->progressive_sequence=1;
|
||||
s->decode_mb= ff_h263_decode_mb;
|
||||
s->low_delay= 1;
|
||||
avctx->pix_fmt= PIX_FMT_YUV420P;
|
||||
@ -85,6 +90,12 @@ int ff_h263_decode_init(AVCodecContext *avctx)
|
||||
s->h263_pred = 1;
|
||||
s->msmpeg4_version=5;
|
||||
break;
|
||||
case CODEC_ID_VC1:
|
||||
case CODEC_ID_WMV3:
|
||||
s->h263_msmpeg4 = 1;
|
||||
s->h263_pred = 1;
|
||||
s->msmpeg4_version=6;
|
||||
break;
|
||||
case CODEC_ID_H263I:
|
||||
break;
|
||||
case CODEC_ID_FLV1:
|
||||
@ -100,15 +111,15 @@ int ff_h263_decode_init(AVCodecContext *avctx)
|
||||
if (MPV_common_init(s) < 0)
|
||||
return -1;
|
||||
|
||||
if (s->h263_msmpeg4)
|
||||
if (ENABLE_MSMPEG4_DECODER && s->h263_msmpeg4)
|
||||
ff_msmpeg4_decode_init(s);
|
||||
else
|
||||
h263_decode_init_vlc(s);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ff_h263_decode_end(AVCodecContext *avctx)
|
||||
av_cold int ff_h263_decode_end(AVCodecContext *avctx)
|
||||
{
|
||||
MpegEncContext *s = avctx->priv_data;
|
||||
|
||||
@ -117,20 +128,20 @@ int ff_h263_decode_end(AVCodecContext *avctx)
|
||||
}
|
||||
|
||||
/**
|
||||
* retunrs the number of bytes consumed for building the current frame
|
||||
* returns the number of bytes consumed for building the current frame
|
||||
*/
|
||||
static int get_consumed_bytes(MpegEncContext *s, int buf_size){
|
||||
int pos= (get_bits_count(&s->gb)+7)>>3;
|
||||
|
||||
|
||||
if(s->divx_packed){
|
||||
//we would have to scan through the whole buf to handle the weird reordering ...
|
||||
return buf_size;
|
||||
return buf_size;
|
||||
}else if(s->flags&CODEC_FLAG_TRUNCATED){
|
||||
pos -= s->parse_context.last_index;
|
||||
if(pos<0) pos=0; // padding is not really read so this might be -1
|
||||
return pos;
|
||||
}else{
|
||||
if(pos==0) pos=1; //avoid infinite loops (i doubt thats needed but ...)
|
||||
if(pos==0) pos=1; //avoid infinite loops (i doubt that is needed but ...)
|
||||
if(pos+10>buf_size) pos=buf_size; // oops ;)
|
||||
|
||||
return pos;
|
||||
@ -139,22 +150,23 @@ static int get_consumed_bytes(MpegEncContext *s, int buf_size){
|
||||
|
||||
static int decode_slice(MpegEncContext *s){
|
||||
const int part_mask= s->partitioned_frame ? (AC_END|AC_ERROR) : 0x7F;
|
||||
const int mb_size= 16>>s->avctx->lowres;
|
||||
s->last_resync_gb= s->gb;
|
||||
s->first_slice_line= 1;
|
||||
|
||||
|
||||
s->resync_mb_x= s->mb_x;
|
||||
s->resync_mb_y= s->mb_y;
|
||||
|
||||
ff_set_qscale(s, s->qscale);
|
||||
|
||||
|
||||
if(s->partitioned_frame){
|
||||
const int qscale= s->qscale;
|
||||
|
||||
if(s->codec_id==CODEC_ID_MPEG4){
|
||||
if(ff_mpeg4_decode_partitions(s) < 0)
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/* restore variables which were modified */
|
||||
s->first_slice_line=1;
|
||||
s->mb_x= s->resync_mb_x;
|
||||
@ -171,13 +183,13 @@ static int decode_slice(MpegEncContext *s){
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(s->msmpeg4_version==1){
|
||||
s->last_dc[0]=
|
||||
s->last_dc[1]=
|
||||
s->last_dc[2]= 128;
|
||||
}
|
||||
|
||||
|
||||
ff_init_block_index(s);
|
||||
for(; s->mb_x < s->mb_width; s->mb_x++) {
|
||||
int ret;
|
||||
@ -185,19 +197,18 @@ static int decode_slice(MpegEncContext *s){
|
||||
ff_update_block_index(s);
|
||||
|
||||
if(s->resync_mb_x == s->mb_x && s->resync_mb_y+1 == s->mb_y){
|
||||
s->first_slice_line=0;
|
||||
s->first_slice_line=0;
|
||||
}
|
||||
|
||||
/* DCT & quantize */
|
||||
s->dsp.clear_blocks(s->block[0]);
|
||||
|
||||
|
||||
s->mv_dir = MV_DIR_FORWARD;
|
||||
s->mv_type = MV_TYPE_16X16;
|
||||
// s->mb_skiped = 0;
|
||||
// s->mb_skipped = 0;
|
||||
//printf("%d %d %06X\n", ret, get_bits_count(&s->gb), show_bits(&s->gb, 24));
|
||||
ret= s->decode_mb(s, s->block);
|
||||
|
||||
if (s->pict_type!=B_TYPE)
|
||||
if (s->pict_type!=FF_B_TYPE)
|
||||
ff_h263_update_motion_val(s);
|
||||
|
||||
if(ret<0){
|
||||
@ -211,13 +222,13 @@ static int decode_slice(MpegEncContext *s){
|
||||
ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, (AC_END|DC_END|MV_END)&part_mask);
|
||||
|
||||
s->padding_bug_score--;
|
||||
|
||||
|
||||
if(++s->mb_x >= s->mb_width){
|
||||
s->mb_x=0;
|
||||
ff_draw_horiz_band(s, s->mb_y*16, 16);
|
||||
ff_draw_horiz_band(s, s->mb_y*mb_size, mb_size);
|
||||
s->mb_y++;
|
||||
}
|
||||
return 0;
|
||||
return 0;
|
||||
}else if(ret==SLICE_NOEND){
|
||||
av_log(s->avctx, AV_LOG_ERROR, "Slice mismatch at MB: %d\n", xy);
|
||||
ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x+1, s->mb_y, (AC_END|DC_END|MV_END)&part_mask);
|
||||
@ -225,7 +236,7 @@ static int decode_slice(MpegEncContext *s){
|
||||
}
|
||||
av_log(s->avctx, AV_LOG_ERROR, "Error at MB: %d\n", xy);
|
||||
ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, (AC_ERROR|DC_ERROR|MV_ERROR)&part_mask);
|
||||
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -233,55 +244,62 @@ static int decode_slice(MpegEncContext *s){
|
||||
if(s->loop_filter)
|
||||
ff_h263_loop_filter(s);
|
||||
}
|
||||
|
||||
ff_draw_horiz_band(s, s->mb_y*16, 16);
|
||||
|
||||
|
||||
ff_draw_horiz_band(s, s->mb_y*mb_size, mb_size);
|
||||
|
||||
s->mb_x= 0;
|
||||
}
|
||||
|
||||
|
||||
assert(s->mb_x==0 && s->mb_y==s->mb_height);
|
||||
|
||||
/* try to detect the padding bug */
|
||||
if( s->codec_id==CODEC_ID_MPEG4
|
||||
&& (s->workaround_bugs&FF_BUG_AUTODETECT)
|
||||
&& (s->workaround_bugs&FF_BUG_AUTODETECT)
|
||||
&& s->gb.size_in_bits - get_bits_count(&s->gb) >=0
|
||||
&& s->gb.size_in_bits - get_bits_count(&s->gb) < 48
|
||||
// && !s->resync_marker
|
||||
&& !s->data_partitioning){
|
||||
|
||||
|
||||
const int bits_count= get_bits_count(&s->gb);
|
||||
const int bits_left = s->gb.size_in_bits - bits_count;
|
||||
|
||||
|
||||
if(bits_left==0){
|
||||
s->padding_bug_score+=16;
|
||||
}else if(bits_left>8){
|
||||
s->padding_bug_score++;
|
||||
} else if(bits_left != 1){
|
||||
int v= show_bits(&s->gb, 8);
|
||||
v|= 0x7F >> (7-(bits_count&7));
|
||||
|
||||
if(v==0x7F)
|
||||
if(v==0x7F && bits_left<=8)
|
||||
s->padding_bug_score--;
|
||||
else if(v==0x7F && ((get_bits_count(&s->gb)+8)&8) && bits_left<=16)
|
||||
s->padding_bug_score+= 4;
|
||||
else
|
||||
s->padding_bug_score++;
|
||||
}
|
||||
s->padding_bug_score++;
|
||||
}
|
||||
}
|
||||
|
||||
// handle formats which dont have unique end markers
|
||||
if(s->workaround_bugs&FF_BUG_AUTODETECT){
|
||||
if(s->padding_bug_score > -2 && !s->data_partitioning /*&& (s->divx_version || !s->resync_marker)*/)
|
||||
s->workaround_bugs |= FF_BUG_NO_PADDING;
|
||||
else
|
||||
s->workaround_bugs &= ~FF_BUG_NO_PADDING;
|
||||
}
|
||||
|
||||
// handle formats which don't have unique end markers
|
||||
if(s->msmpeg4_version || (s->workaround_bugs&FF_BUG_NO_PADDING)){ //FIXME perhaps solve this more cleanly
|
||||
int left= s->gb.size_in_bits - get_bits_count(&s->gb);
|
||||
int max_extra=7;
|
||||
|
||||
|
||||
/* no markers in M$ crap */
|
||||
if(s->msmpeg4_version && s->pict_type==I_TYPE)
|
||||
if(s->msmpeg4_version && s->pict_type==FF_I_TYPE)
|
||||
max_extra+= 17;
|
||||
|
||||
|
||||
/* buggy padding but the frame should still end approximately at the bitstream end */
|
||||
if((s->workaround_bugs&FF_BUG_NO_PADDING) && s->error_resilience>=3)
|
||||
max_extra+= 48;
|
||||
else if((s->workaround_bugs&FF_BUG_NO_PADDING))
|
||||
max_extra+= 256*256*256*64;
|
||||
|
||||
|
||||
if(left>max_extra){
|
||||
av_log(s->avctx, AV_LOG_ERROR, "discarding %d junk bits at end, next would be %X\n", left, show_bits(&s->gb, 24));
|
||||
}
|
||||
@ -289,114 +307,38 @@ static int decode_slice(MpegEncContext *s){
|
||||
av_log(s->avctx, AV_LOG_ERROR, "overreading %d bits\n", -left);
|
||||
}else
|
||||
ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, AC_END|DC_END|MV_END);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
av_log(s->avctx, AV_LOG_ERROR, "slice end not reached but screenspace end (%d left %06X, score= %d)\n",
|
||||
av_log(s->avctx, AV_LOG_ERROR, "slice end not reached but screenspace end (%d left %06X, score= %d)\n",
|
||||
s->gb.size_in_bits - get_bits_count(&s->gb),
|
||||
show_bits(&s->gb, 24), s->padding_bug_score);
|
||||
|
||||
|
||||
ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, (AC_END|DC_END|MV_END)&part_mask);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* finds the end of the current frame in the bitstream.
|
||||
* @return the position of the first byte of the next frame, or -1
|
||||
*/
|
||||
static int mpeg4_find_frame_end(MpegEncContext *s, uint8_t *buf, int buf_size){
|
||||
ParseContext *pc= &s->parse_context;
|
||||
int vop_found, i;
|
||||
uint32_t state;
|
||||
|
||||
vop_found= pc->frame_start_found;
|
||||
state= pc->state;
|
||||
|
||||
i=0;
|
||||
if(!vop_found){
|
||||
for(i=0; i<buf_size; i++){
|
||||
state= (state<<8) | buf[i];
|
||||
if(state == 0x1B6){
|
||||
i++;
|
||||
vop_found=1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(vop_found){
|
||||
for(; i<buf_size; i++){
|
||||
state= (state<<8) | buf[i];
|
||||
if((state&0xFFFFFF00) == 0x100){
|
||||
pc->frame_start_found=0;
|
||||
pc->state=-1;
|
||||
return i-3;
|
||||
}
|
||||
}
|
||||
}
|
||||
pc->frame_start_found= vop_found;
|
||||
pc->state= state;
|
||||
return END_NOT_FOUND;
|
||||
}
|
||||
|
||||
static int h263_find_frame_end(MpegEncContext *s, uint8_t *buf, int buf_size){
|
||||
ParseContext *pc= &s->parse_context;
|
||||
int vop_found, i;
|
||||
uint32_t state;
|
||||
|
||||
vop_found= pc->frame_start_found;
|
||||
state= pc->state;
|
||||
|
||||
i=0;
|
||||
if(!vop_found){
|
||||
for(i=0; i<buf_size; i++){
|
||||
state= (state<<8) | buf[i];
|
||||
if(state>>(32-22) == 0x20){
|
||||
i++;
|
||||
vop_found=1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(vop_found){
|
||||
for(; i<buf_size; i++){
|
||||
state= (state<<8) | buf[i];
|
||||
if(state>>(32-22) == 0x20){
|
||||
pc->frame_start_found=0;
|
||||
pc->state=-1;
|
||||
return i-3;
|
||||
}
|
||||
}
|
||||
}
|
||||
pc->frame_start_found= vop_found;
|
||||
pc->state= state;
|
||||
|
||||
return END_NOT_FOUND;
|
||||
}
|
||||
|
||||
int ff_h263_decode_frame(AVCodecContext *avctx,
|
||||
int ff_h263_decode_frame(AVCodecContext *avctx,
|
||||
void *data, int *data_size,
|
||||
uint8_t *buf, int buf_size)
|
||||
const uint8_t *buf, int buf_size)
|
||||
{
|
||||
MpegEncContext *s = avctx->priv_data;
|
||||
int ret;
|
||||
AVFrame *pict = data;
|
||||
|
||||
AVFrame *pict = data;
|
||||
|
||||
#ifdef PRINT_FRAME_TIME
|
||||
uint64_t time= rdtsc();
|
||||
#endif
|
||||
#ifdef DEBUG
|
||||
printf("*****frame %d size=%d\n", avctx->frame_number, buf_size);
|
||||
printf("bytes=%x %x %x %x\n", buf[0], buf[1], buf[2], buf[3]);
|
||||
av_log(avctx, AV_LOG_DEBUG, "*****frame %d size=%d\n", avctx->frame_number, buf_size);
|
||||
if(buf_size>0)
|
||||
av_log(avctx, AV_LOG_DEBUG, "bytes=%x %x %x %x\n", buf[0], buf[1], buf[2], buf[3]);
|
||||
#endif
|
||||
s->flags= avctx->flags;
|
||||
s->flags2= avctx->flags2;
|
||||
|
||||
*data_size = 0;
|
||||
|
||||
/* no supplementary picture */
|
||||
if (buf_size == 0) {
|
||||
/* special case for last picture */
|
||||
@ -412,23 +354,23 @@ uint64_t time= rdtsc();
|
||||
|
||||
if(s->flags&CODEC_FLAG_TRUNCATED){
|
||||
int next;
|
||||
|
||||
if(s->codec_id==CODEC_ID_MPEG4){
|
||||
next= mpeg4_find_frame_end(s, buf, buf_size);
|
||||
}else if(s->codec_id==CODEC_ID_H263){
|
||||
next= h263_find_frame_end(s, buf, buf_size);
|
||||
|
||||
if(ENABLE_MPEG4_DECODER && s->codec_id==CODEC_ID_MPEG4){
|
||||
next= ff_mpeg4_find_frame_end(&s->parse_context, buf, buf_size);
|
||||
}else if(ENABLE_H263_DECODER && s->codec_id==CODEC_ID_H263){
|
||||
next= ff_h263_find_frame_end(&s->parse_context, buf, buf_size);
|
||||
}else{
|
||||
av_log(s->avctx, AV_LOG_ERROR, "this codec doesnt support truncated bitstreams\n");
|
||||
av_log(s->avctx, AV_LOG_ERROR, "this codec does not support truncated bitstreams\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if( ff_combine_frame(s, next, &buf, &buf_size) < 0 )
|
||||
|
||||
if( ff_combine_frame(&s->parse_context, next, (const uint8_t **)&buf, &buf_size) < 0 )
|
||||
return buf_size;
|
||||
}
|
||||
|
||||
|
||||
|
||||
retry:
|
||||
|
||||
|
||||
if(s->bitstream_buffer_size && (s->divx_packed || buf_size<20)){ //divx 5.01+/xvid frame reorder
|
||||
init_get_bits(&s->gb, s->bitstream_buffer, s->bitstream_buffer_size*8);
|
||||
}else
|
||||
@ -439,22 +381,23 @@ retry:
|
||||
if (MPV_common_init(s) < 0) //we need the idct permutaton for reading a custom matrix
|
||||
return -1;
|
||||
}
|
||||
|
||||
//we need to set current_picture_ptr before reading the header, otherwise we cant store anyting im there
|
||||
|
||||
/* We need to set current_picture_ptr before reading the header,
|
||||
* otherwise we cannot store anyting in there */
|
||||
if(s->current_picture_ptr==NULL || s->current_picture_ptr->data[0]){
|
||||
int i= ff_find_unused_picture(s, 0);
|
||||
s->current_picture_ptr= &s->picture[i];
|
||||
}
|
||||
|
||||
|
||||
/* let's go :-) */
|
||||
if (s->msmpeg4_version==5) {
|
||||
if (ENABLE_WMV2_DECODER && s->msmpeg4_version==5) {
|
||||
ret= ff_wmv2_decode_picture_header(s);
|
||||
} else if (s->msmpeg4_version) {
|
||||
} else if (ENABLE_MSMPEG4_DECODER && s->msmpeg4_version) {
|
||||
ret = msmpeg4_decode_picture_header(s);
|
||||
} else if (s->h263_pred) {
|
||||
if(s->avctx->extradata_size && s->picture_number==0){
|
||||
GetBitContext gb;
|
||||
|
||||
|
||||
init_get_bits(&gb, s->avctx->extradata, s->avctx->extradata_size*8);
|
||||
ret = ff_mpeg4_decode_picture_header(s, &gb);
|
||||
}
|
||||
@ -469,63 +412,67 @@ retry:
|
||||
} else {
|
||||
ret = h263_decode_picture_header(s);
|
||||
}
|
||||
|
||||
if(ret==FRAME_SKIPED) return get_consumed_bytes(s, buf_size);
|
||||
|
||||
if(ret==FRAME_SKIPPED) return get_consumed_bytes(s, buf_size);
|
||||
|
||||
/* skip if the header was thrashed */
|
||||
if (ret < 0){
|
||||
av_log(s->avctx, AV_LOG_ERROR, "header damaged\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
avctx->has_b_frames= !s->low_delay;
|
||||
|
||||
|
||||
if(s->xvid_build==0 && s->divx_version==0 && s->lavc_build==0){
|
||||
if(s->avctx->stream_codec_tag == ff_get_fourcc("XVID") ||
|
||||
s->avctx->codec_tag == ff_get_fourcc("XVID") || s->avctx->codec_tag == ff_get_fourcc("XVIX"))
|
||||
if(s->stream_codec_tag == ff_get_fourcc("XVID") ||
|
||||
s->codec_tag == ff_get_fourcc("XVID") || s->codec_tag == ff_get_fourcc("XVIX") ||
|
||||
s->codec_tag == ff_get_fourcc("RMP4"))
|
||||
s->xvid_build= -1;
|
||||
#if 0
|
||||
if(s->avctx->codec_tag == ff_get_fourcc("DIVX") && s->vo_type==0 && s->vol_control_parameters==1
|
||||
&& s->padding_bug_score > 0 && s->low_delay) // XVID with modified fourcc
|
||||
if(s->codec_tag == ff_get_fourcc("DIVX") && s->vo_type==0 && s->vol_control_parameters==1
|
||||
&& s->padding_bug_score > 0 && s->low_delay) // XVID with modified fourcc
|
||||
s->xvid_build= -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
if(s->xvid_build==0 && s->divx_version==0 && s->lavc_build==0){
|
||||
if(s->avctx->codec_tag == ff_get_fourcc("DIVX") && s->vo_type==0 && s->vol_control_parameters==0)
|
||||
if(s->codec_tag == ff_get_fourcc("DIVX") && s->vo_type==0 && s->vol_control_parameters==0)
|
||||
s->divx_version= 400; //divx 4
|
||||
}
|
||||
|
||||
if(s->workaround_bugs&FF_BUG_AUTODETECT){
|
||||
s->workaround_bugs &= ~FF_BUG_NO_PADDING;
|
||||
|
||||
if(s->padding_bug_score > -2 && !s->data_partitioning && (s->divx_version || !s->resync_marker))
|
||||
s->workaround_bugs |= FF_BUG_NO_PADDING;
|
||||
if(s->xvid_build && s->divx_version){
|
||||
s->divx_version=
|
||||
s->divx_build= 0;
|
||||
}
|
||||
|
||||
if(s->avctx->codec_tag == ff_get_fourcc("XVIX"))
|
||||
if(s->workaround_bugs&FF_BUG_AUTODETECT){
|
||||
if(s->codec_tag == ff_get_fourcc("XVIX"))
|
||||
s->workaround_bugs|= FF_BUG_XVID_ILACE;
|
||||
|
||||
if(s->avctx->codec_tag == ff_get_fourcc("UMP4")){
|
||||
if(s->codec_tag == ff_get_fourcc("UMP4")){
|
||||
s->workaround_bugs|= FF_BUG_UMP4;
|
||||
}
|
||||
|
||||
if(s->divx_version>=500){
|
||||
if(s->divx_version>=500 && s->divx_build<1814){
|
||||
s->workaround_bugs|= FF_BUG_QPEL_CHROMA;
|
||||
}
|
||||
|
||||
if(s->divx_version>502){
|
||||
if(s->divx_version>502 && s->divx_build<1814){
|
||||
s->workaround_bugs|= FF_BUG_QPEL_CHROMA2;
|
||||
}
|
||||
|
||||
if(s->xvid_build && s->xvid_build<=3)
|
||||
s->padding_bug_score= 256*256*256*64;
|
||||
|
||||
|
||||
if(s->xvid_build && s->xvid_build<=1)
|
||||
s->workaround_bugs|= FF_BUG_QPEL_CHROMA;
|
||||
|
||||
if(s->xvid_build && s->xvid_build<=12)
|
||||
s->workaround_bugs|= FF_BUG_EDGE;
|
||||
|
||||
if(s->xvid_build && s->xvid_build<=32)
|
||||
s->workaround_bugs|= FF_BUG_DC_CLIP;
|
||||
|
||||
#define SET_QPEL_FUNC(postfix1, postfix2) \
|
||||
s->dsp.put_ ## postfix1 = ff_put_ ## postfix2;\
|
||||
s->dsp.put_no_rnd_ ## postfix1 = ff_put_no_rnd_ ## postfix2;\
|
||||
@ -533,7 +480,7 @@ retry:
|
||||
|
||||
if(s->lavc_build && s->lavc_build<4653)
|
||||
s->workaround_bugs|= FF_BUG_STD_QPEL;
|
||||
|
||||
|
||||
if(s->lavc_build && s->lavc_build<4655)
|
||||
s->workaround_bugs|= FF_BUG_DIRECT_BLOCKSIZE;
|
||||
|
||||
@ -541,6 +488,9 @@ retry:
|
||||
s->workaround_bugs|= FF_BUG_EDGE;
|
||||
}
|
||||
|
||||
if(s->lavc_build && s->lavc_build<=4712)
|
||||
s->workaround_bugs|= FF_BUG_DC_CLIP;
|
||||
|
||||
if(s->divx_version)
|
||||
s->workaround_bugs|= FF_BUG_DIRECT_BLOCKSIZE;
|
||||
//printf("padding_bug_score: %d\n", s->padding_bug_score);
|
||||
@ -550,23 +500,25 @@ retry:
|
||||
if(s->divx_version && s->divx_version<500){
|
||||
s->workaround_bugs|= FF_BUG_EDGE;
|
||||
}
|
||||
|
||||
|
||||
if(s->divx_version)
|
||||
s->workaround_bugs|= FF_BUG_HPEL_CHROMA;
|
||||
#if 0
|
||||
if(s->divx_version==500)
|
||||
s->padding_bug_score= 256*256*256*64;
|
||||
|
||||
/* very ugly XVID padding bug detection FIXME/XXX solve this differently
|
||||
* lets hope this at least works
|
||||
* Let us hope this at least works.
|
||||
*/
|
||||
if( s->resync_marker==0 && s->data_partitioning==0 && s->divx_version==0
|
||||
&& s->codec_id==CODEC_ID_MPEG4 && s->vo_type==0)
|
||||
s->workaround_bugs|= FF_BUG_NO_PADDING;
|
||||
|
||||
|
||||
if(s->lavc_build && s->lavc_build<4609) //FIXME not sure about the version num but a 4609 file seems ok
|
||||
s->workaround_bugs|= FF_BUG_NO_PADDING;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
if(s->workaround_bugs& FF_BUG_STD_QPEL){
|
||||
SET_QPEL_FUNC(qpel_pixels_tab[0][ 5], qpel16_mc11_old_c)
|
||||
SET_QPEL_FUNC(qpel_pixels_tab[0][ 7], qpel16_mc31_old_c)
|
||||
@ -584,10 +536,10 @@ retry:
|
||||
}
|
||||
|
||||
if(avctx->debug & FF_DEBUG_BUGS)
|
||||
av_log(s->avctx, AV_LOG_DEBUG, "bugs: %X lavc_build:%d xvid_build:%d divx_version:%d divx_build:%d %s\n",
|
||||
av_log(s->avctx, AV_LOG_DEBUG, "bugs: %X lavc_build:%d xvid_build:%d divx_version:%d divx_build:%d %s\n",
|
||||
s->workaround_bugs, s->lavc_build, s->xvid_build, s->divx_version, s->divx_build,
|
||||
s->divx_packed ? "p" : "");
|
||||
|
||||
|
||||
#if 0 // dump bits per frame / qp / complexity
|
||||
{
|
||||
static FILE *f=NULL;
|
||||
@ -595,13 +547,23 @@ retry:
|
||||
fprintf(f, "%d %d %f\n", buf_size, s->qscale, buf_size*(double)s->qscale);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(HAVE_MMX)
|
||||
if(s->codec_id == CODEC_ID_MPEG4 && s->xvid_build && avctx->idct_algo == FF_IDCT_AUTO && (mm_flags & MM_MMX)){
|
||||
avctx->idct_algo= FF_IDCT_XVIDMMX;
|
||||
avctx->coded_width= 0; // force reinit
|
||||
// dsputil_init(&s->dsp, avctx);
|
||||
s->picture_number=0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* After H263 & mpeg4 header decode we have the height, width,*/
|
||||
/* and other parameters. So then we could init the picture */
|
||||
/* FIXME: By the way H263 decoder is evolving it should have */
|
||||
/* an H263EncContext */
|
||||
|
||||
if ( s->width != avctx->width || s->height != avctx->height) {
|
||||
|
||||
if ( s->width != avctx->coded_width
|
||||
|| s->height != avctx->coded_height) {
|
||||
/* H.263 could change picture size any time */
|
||||
ParseContext pc= s->parse_context; //FIXME move these demuxng hack to avformat
|
||||
s->parse_context.buffer=0;
|
||||
@ -609,81 +571,95 @@ retry:
|
||||
s->parse_context= pc;
|
||||
}
|
||||
if (!s->context_initialized) {
|
||||
avctx->width = s->width;
|
||||
avctx->height = s->height;
|
||||
avcodec_set_dimensions(avctx, s->width, s->height);
|
||||
|
||||
goto retry;
|
||||
}
|
||||
|
||||
if((s->codec_id==CODEC_ID_H263 || s->codec_id==CODEC_ID_H263P))
|
||||
s->gob_index = ff_h263_get_gob_height(s);
|
||||
|
||||
|
||||
// for hurry_up==5
|
||||
s->current_picture.pict_type= s->pict_type;
|
||||
s->current_picture.key_frame= s->pict_type == I_TYPE;
|
||||
s->current_picture.key_frame= s->pict_type == FF_I_TYPE;
|
||||
|
||||
/* skip b frames if we dont have reference frames */
|
||||
if(s->last_picture_ptr==NULL && s->pict_type==B_TYPE) return get_consumed_bytes(s, buf_size);
|
||||
/* skip B-frames if we don't have reference frames */
|
||||
if(s->last_picture_ptr==NULL && (s->pict_type==FF_B_TYPE || s->dropable)) return get_consumed_bytes(s, buf_size);
|
||||
/* skip b frames if we are in a hurry */
|
||||
if(avctx->hurry_up && s->pict_type==B_TYPE) return get_consumed_bytes(s, buf_size);
|
||||
if(avctx->hurry_up && s->pict_type==FF_B_TYPE) return get_consumed_bytes(s, buf_size);
|
||||
if( (avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type==FF_B_TYPE)
|
||||
|| (avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type!=FF_I_TYPE)
|
||||
|| avctx->skip_frame >= AVDISCARD_ALL)
|
||||
return get_consumed_bytes(s, buf_size);
|
||||
/* skip everything if we are in a hurry>=5 */
|
||||
if(avctx->hurry_up>=5) return get_consumed_bytes(s, buf_size);
|
||||
|
||||
|
||||
if(s->next_p_frame_damaged){
|
||||
if(s->pict_type==B_TYPE)
|
||||
if(s->pict_type==FF_B_TYPE)
|
||||
return get_consumed_bytes(s, buf_size);
|
||||
else
|
||||
s->next_p_frame_damaged=0;
|
||||
}
|
||||
|
||||
if((s->avctx->flags2 & CODEC_FLAG2_FAST) && s->pict_type==FF_B_TYPE){
|
||||
s->me.qpel_put= s->dsp.put_2tap_qpel_pixels_tab;
|
||||
s->me.qpel_avg= s->dsp.avg_2tap_qpel_pixels_tab;
|
||||
}else if((!s->no_rounding) || s->pict_type==FF_B_TYPE){
|
||||
s->me.qpel_put= s->dsp.put_qpel_pixels_tab;
|
||||
s->me.qpel_avg= s->dsp.avg_qpel_pixels_tab;
|
||||
}else{
|
||||
s->me.qpel_put= s->dsp.put_no_rnd_qpel_pixels_tab;
|
||||
s->me.qpel_avg= s->dsp.avg_qpel_pixels_tab;
|
||||
}
|
||||
|
||||
if(MPV_frame_start(s, avctx) < 0)
|
||||
return -1;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("qscale=%d\n", s->qscale);
|
||||
av_log(avctx, AV_LOG_DEBUG, "qscale=%d\n", s->qscale);
|
||||
#endif
|
||||
|
||||
ff_er_frame_start(s);
|
||||
|
||||
|
||||
//the second part of the wmv2 header contains the MB skip bits which are stored in current_picture->mb_type
|
||||
//which isnt available before MPV_frame_start()
|
||||
if (s->msmpeg4_version==5){
|
||||
if(ff_wmv2_decode_secondary_picture_header(s) < 0)
|
||||
return -1;
|
||||
//which is not available before MPV_frame_start()
|
||||
if (ENABLE_WMV2_DECODER && s->msmpeg4_version==5){
|
||||
ret = ff_wmv2_decode_secondary_picture_header(s);
|
||||
if(ret<0) return ret;
|
||||
if(ret==1) goto intrax8_decoded;
|
||||
}
|
||||
|
||||
/* decode each macroblock */
|
||||
s->mb_x=0;
|
||||
s->mb_x=0;
|
||||
s->mb_y=0;
|
||||
|
||||
|
||||
decode_slice(s);
|
||||
while(s->mb_y<s->mb_height){
|
||||
if(s->msmpeg4_version){
|
||||
if(s->mb_x!=0 || (s->mb_y%s->slice_height)!=0 || get_bits_count(&s->gb) > s->gb.size_in_bits)
|
||||
if(s->slice_height==0 || s->mb_x!=0 || (s->mb_y%s->slice_height)!=0 || get_bits_count(&s->gb) > s->gb.size_in_bits)
|
||||
break;
|
||||
}else{
|
||||
if(ff_h263_resync(s)<0)
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if(s->msmpeg4_version<4 && s->h263_pred)
|
||||
ff_mpeg4_clean_buffers(s);
|
||||
|
||||
decode_slice(s);
|
||||
}
|
||||
|
||||
if (s->h263_msmpeg4 && s->msmpeg4_version<4 && s->pict_type==I_TYPE)
|
||||
if(msmpeg4_decode_ext_header(s, buf_size) < 0){
|
||||
if (s->h263_msmpeg4 && s->msmpeg4_version<4 && s->pict_type==FF_I_TYPE)
|
||||
if(!ENABLE_MSMPEG4_DECODER || msmpeg4_decode_ext_header(s, buf_size) < 0){
|
||||
s->error_status_table[s->mb_num-1]= AC_ERROR|DC_ERROR|MV_ERROR;
|
||||
}
|
||||
|
||||
|
||||
/* divx 5.01+ bistream reorder stuff */
|
||||
if(s->codec_id==CODEC_ID_MPEG4 && s->bitstream_buffer_size==0 && s->divx_packed){
|
||||
int current_pos= get_bits_count(&s->gb)>>3;
|
||||
int startcode_found=0;
|
||||
|
||||
if( buf_size - current_pos > 5
|
||||
&& buf_size - current_pos < BITSTREAM_BUFFER_SIZE){
|
||||
if(buf_size - current_pos > 5){
|
||||
int i;
|
||||
for(i=current_pos; i<buf_size-3; i++){
|
||||
if(buf[i]==0 && buf[i+1]==0 && buf[i+2]==1 && buf[i+3]==0xB6){
|
||||
@ -698,45 +674,44 @@ retry:
|
||||
}
|
||||
|
||||
if(startcode_found){
|
||||
s->bitstream_buffer= av_fast_realloc(
|
||||
s->bitstream_buffer,
|
||||
&s->allocated_bitstream_buffer_size,
|
||||
buf_size - current_pos + FF_INPUT_BUFFER_PADDING_SIZE);
|
||||
memcpy(s->bitstream_buffer, buf + current_pos, buf_size - current_pos);
|
||||
s->bitstream_buffer_size= buf_size - current_pos;
|
||||
}
|
||||
}
|
||||
|
||||
intrax8_decoded:
|
||||
ff_er_frame_end(s);
|
||||
|
||||
MPV_frame_end(s);
|
||||
|
||||
assert(s->current_picture.pict_type == s->current_picture_ptr->pict_type);
|
||||
assert(s->current_picture.pict_type == s->pict_type);
|
||||
if(s->pict_type==B_TYPE || s->low_delay){
|
||||
*pict= *(AVFrame*)&s->current_picture;
|
||||
ff_print_debug_info(s, pict);
|
||||
} else {
|
||||
*pict= *(AVFrame*)&s->last_picture;
|
||||
if (s->pict_type == FF_B_TYPE || s->low_delay) {
|
||||
*pict= *(AVFrame*)s->current_picture_ptr;
|
||||
} else if (s->last_picture_ptr != NULL) {
|
||||
*pict= *(AVFrame*)s->last_picture_ptr;
|
||||
}
|
||||
|
||||
if(s->last_picture_ptr || s->low_delay){
|
||||
*data_size = sizeof(AVFrame);
|
||||
ff_print_debug_info(s, pict);
|
||||
}
|
||||
|
||||
/* Return the Picture timestamp as the frame number */
|
||||
/* we substract 1 because it is added on utils.c */
|
||||
/* we subtract 1 because it is added on utils.c */
|
||||
avctx->frame_number = s->picture_number - 1;
|
||||
|
||||
/* dont output the last pic after seeking */
|
||||
if(s->last_picture_ptr || s->low_delay)
|
||||
*data_size = sizeof(AVFrame);
|
||||
#ifdef PRINT_FRAME_TIME
|
||||
printf("%Ld\n", rdtsc()-time);
|
||||
av_log(avctx, AV_LOG_DEBUG, "%"PRId64"\n", rdtsc()-time);
|
||||
#endif
|
||||
|
||||
return get_consumed_bytes(s, buf_size);
|
||||
}
|
||||
|
||||
static const AVOption mpeg4_decoptions[] =
|
||||
{
|
||||
AVOPTION_SUB(avoptions_workaround_bug),
|
||||
AVOPTION_END()
|
||||
};
|
||||
|
||||
AVCodec mpeg4_decoder = {
|
||||
"mpeg4",
|
||||
CODEC_TYPE_VIDEO,
|
||||
@ -746,9 +721,9 @@ AVCodec mpeg4_decoder = {
|
||||
NULL,
|
||||
ff_h263_decode_end,
|
||||
ff_h263_decode_frame,
|
||||
CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED,
|
||||
.options = mpeg4_decoptions,
|
||||
CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY,
|
||||
.flush= ff_mpeg_flush,
|
||||
.long_name= NULL_IF_CONFIG_SMALL("MPEG-4 part 2"),
|
||||
};
|
||||
|
||||
AVCodec h263_decoder = {
|
||||
@ -760,8 +735,9 @@ AVCodec h263_decoder = {
|
||||
NULL,
|
||||
ff_h263_decode_end,
|
||||
ff_h263_decode_frame,
|
||||
CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED,
|
||||
CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY,
|
||||
.flush= ff_mpeg_flush,
|
||||
.long_name= NULL_IF_CONFIG_SMALL("H.263"),
|
||||
};
|
||||
|
||||
AVCodec msmpeg4v1_decoder = {
|
||||
@ -774,7 +750,7 @@ AVCodec msmpeg4v1_decoder = {
|
||||
ff_h263_decode_end,
|
||||
ff_h263_decode_frame,
|
||||
CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1,
|
||||
mpeg4_decoptions,
|
||||
.long_name= NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Microsoft variant version 1"),
|
||||
};
|
||||
|
||||
AVCodec msmpeg4v2_decoder = {
|
||||
@ -787,7 +763,7 @@ AVCodec msmpeg4v2_decoder = {
|
||||
ff_h263_decode_end,
|
||||
ff_h263_decode_frame,
|
||||
CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1,
|
||||
mpeg4_decoptions,
|
||||
.long_name= NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Microsoft variant version 2"),
|
||||
};
|
||||
|
||||
AVCodec msmpeg4v3_decoder = {
|
||||
@ -800,7 +776,7 @@ AVCodec msmpeg4v3_decoder = {
|
||||
ff_h263_decode_end,
|
||||
ff_h263_decode_frame,
|
||||
CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1,
|
||||
.options = mpeg4_decoptions,
|
||||
.long_name= NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Microsoft variant version 3"),
|
||||
};
|
||||
|
||||
AVCodec wmv1_decoder = {
|
||||
@ -813,7 +789,7 @@ AVCodec wmv1_decoder = {
|
||||
ff_h263_decode_end,
|
||||
ff_h263_decode_frame,
|
||||
CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1,
|
||||
mpeg4_decoptions,
|
||||
.long_name= NULL_IF_CONFIG_SMALL("Windows Media Video 7"),
|
||||
};
|
||||
|
||||
AVCodec h263i_decoder = {
|
||||
@ -826,7 +802,7 @@ AVCodec h263i_decoder = {
|
||||
ff_h263_decode_end,
|
||||
ff_h263_decode_frame,
|
||||
CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1,
|
||||
mpeg4_decoptions,
|
||||
.long_name = NULL_IF_CONFIG_SMALL("H.263i"),
|
||||
};
|
||||
|
||||
AVCodec flv_decoder = {
|
||||
@ -838,5 +814,6 @@ AVCodec flv_decoder = {
|
||||
NULL,
|
||||
ff_h263_decode_end,
|
||||
ff_h263_decode_frame,
|
||||
CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1
|
||||
CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1,
|
||||
.long_name= NULL_IF_CONFIG_SMALL("Flash Video"),
|
||||
};
|
||||
|
File diff suppressed because it is too large
Load Diff
438
src/add-ons/media/plugins/avcodec/libavcodec/h264.h
Normal file
438
src/add-ons/media/plugins/avcodec/libavcodec/h264.h
Normal file
@ -0,0 +1,438 @@
|
||||
/*
|
||||
* H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder
|
||||
* Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg 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,
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file h264.h
|
||||
* H.264 / AVC / MPEG4 part10 codec.
|
||||
* @author Michael Niedermayer <michaelni@gmx.at>
|
||||
*/
|
||||
|
||||
#ifndef FFMPEG_H264_H
|
||||
#define FFMPEG_H264_H
|
||||
|
||||
#include "dsputil.h"
|
||||
#include "cabac.h"
|
||||
#include "mpegvideo.h"
|
||||
#include "h264pred.h"
|
||||
|
||||
#define interlaced_dct interlaced_dct_is_a_bad_name
|
||||
#define mb_intra mb_intra_is_not_initialized_see_mb_type
|
||||
|
||||
#define LUMA_DC_BLOCK_INDEX 25
|
||||
#define CHROMA_DC_BLOCK_INDEX 26
|
||||
|
||||
#define CHROMA_DC_COEFF_TOKEN_VLC_BITS 8
|
||||
#define COEFF_TOKEN_VLC_BITS 8
|
||||
#define TOTAL_ZEROS_VLC_BITS 9
|
||||
#define CHROMA_DC_TOTAL_ZEROS_VLC_BITS 3
|
||||
#define RUN_VLC_BITS 3
|
||||
#define RUN7_VLC_BITS 6
|
||||
|
||||
#define MAX_SPS_COUNT 32
|
||||
#define MAX_PPS_COUNT 256
|
||||
|
||||
#define MAX_MMCO_COUNT 66
|
||||
|
||||
#define MAX_DELAYED_PIC_COUNT 16
|
||||
|
||||
/* Compiling in interlaced support reduces the speed
|
||||
* of progressive decoding by about 2%. */
|
||||
#define ALLOW_INTERLACE
|
||||
|
||||
#define ALLOW_NOCHROMA
|
||||
|
||||
#ifdef ALLOW_INTERLACE
|
||||
#define MB_MBAFF h->mb_mbaff
|
||||
#define MB_FIELD h->mb_field_decoding_flag
|
||||
#define FRAME_MBAFF h->mb_aff_frame
|
||||
#define FIELD_PICTURE (s->picture_structure != PICT_FRAME)
|
||||
#else
|
||||
#define MB_MBAFF 0
|
||||
#define MB_FIELD 0
|
||||
#define FRAME_MBAFF 0
|
||||
#define FIELD_PICTURE 0
|
||||
#undef IS_INTERLACED
|
||||
#define IS_INTERLACED(mb_type) 0
|
||||
#endif
|
||||
#define FIELD_OR_MBAFF_PICTURE (FRAME_MBAFF || FIELD_PICTURE)
|
||||
|
||||
#ifdef ALLOW_NOCHROMA
|
||||
#define CHROMA h->sps.chroma_format_idc
|
||||
#else
|
||||
#define CHROMA 1
|
||||
#endif
|
||||
|
||||
#ifndef ENABLE_H264_ENCODER
|
||||
#define ENABLE_H264_ENCODER 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Sequence parameter set
|
||||
*/
|
||||
typedef struct SPS{
|
||||
|
||||
int profile_idc;
|
||||
int level_idc;
|
||||
int chroma_format_idc;
|
||||
int transform_bypass; ///< qpprime_y_zero_transform_bypass_flag
|
||||
int log2_max_frame_num; ///< log2_max_frame_num_minus4 + 4
|
||||
int poc_type; ///< pic_order_cnt_type
|
||||
int log2_max_poc_lsb; ///< log2_max_pic_order_cnt_lsb_minus4
|
||||
int delta_pic_order_always_zero_flag;
|
||||
int offset_for_non_ref_pic;
|
||||
int offset_for_top_to_bottom_field;
|
||||
int poc_cycle_length; ///< num_ref_frames_in_pic_order_cnt_cycle
|
||||
int ref_frame_count; ///< num_ref_frames
|
||||
int gaps_in_frame_num_allowed_flag;
|
||||
int mb_width; ///< pic_width_in_mbs_minus1 + 1
|
||||
int mb_height; ///< pic_height_in_map_units_minus1 + 1
|
||||
int frame_mbs_only_flag;
|
||||
int mb_aff; ///<mb_adaptive_frame_field_flag
|
||||
int direct_8x8_inference_flag;
|
||||
int crop; ///< frame_cropping_flag
|
||||
unsigned int crop_left; ///< frame_cropping_rect_left_offset
|
||||
unsigned int crop_right; ///< frame_cropping_rect_right_offset
|
||||
unsigned int crop_top; ///< frame_cropping_rect_top_offset
|
||||
unsigned int crop_bottom; ///< frame_cropping_rect_bottom_offset
|
||||
int vui_parameters_present_flag;
|
||||
AVRational sar;
|
||||
int timing_info_present_flag;
|
||||
uint32_t num_units_in_tick;
|
||||
uint32_t time_scale;
|
||||
int fixed_frame_rate_flag;
|
||||
short offset_for_ref_frame[256]; //FIXME dyn aloc?
|
||||
int bitstream_restriction_flag;
|
||||
int num_reorder_frames;
|
||||
int scaling_matrix_present;
|
||||
uint8_t scaling_matrix4[6][16];
|
||||
uint8_t scaling_matrix8[2][64];
|
||||
}SPS;
|
||||
|
||||
/**
|
||||
* Picture parameter set
|
||||
*/
|
||||
typedef struct PPS{
|
||||
unsigned int sps_id;
|
||||
int cabac; ///< entropy_coding_mode_flag
|
||||
int pic_order_present; ///< pic_order_present_flag
|
||||
int slice_group_count; ///< num_slice_groups_minus1 + 1
|
||||
int mb_slice_group_map_type;
|
||||
unsigned int ref_count[2]; ///< num_ref_idx_l0/1_active_minus1 + 1
|
||||
int weighted_pred; ///< weighted_pred_flag
|
||||
int weighted_bipred_idc;
|
||||
int init_qp; ///< pic_init_qp_minus26 + 26
|
||||
int init_qs; ///< pic_init_qs_minus26 + 26
|
||||
int chroma_qp_index_offset[2];
|
||||
int deblocking_filter_parameters_present; ///< deblocking_filter_parameters_present_flag
|
||||
int constrained_intra_pred; ///< constrained_intra_pred_flag
|
||||
int redundant_pic_cnt_present; ///< redundant_pic_cnt_present_flag
|
||||
int transform_8x8_mode; ///< transform_8x8_mode_flag
|
||||
uint8_t scaling_matrix4[6][16];
|
||||
uint8_t scaling_matrix8[2][64];
|
||||
uint8_t chroma_qp_table[2][64]; ///< pre-scaled (with chroma_qp_index_offset) version of qp_table
|
||||
int chroma_qp_diff;
|
||||
}PPS;
|
||||
|
||||
/**
|
||||
* Memory management control operation opcode.
|
||||
*/
|
||||
typedef enum MMCOOpcode{
|
||||
MMCO_END=0,
|
||||
MMCO_SHORT2UNUSED,
|
||||
MMCO_LONG2UNUSED,
|
||||
MMCO_SHORT2LONG,
|
||||
MMCO_SET_MAX_LONG,
|
||||
MMCO_RESET,
|
||||
MMCO_LONG,
|
||||
} MMCOOpcode;
|
||||
|
||||
/**
|
||||
* Memory management control operation.
|
||||
*/
|
||||
typedef struct MMCO{
|
||||
MMCOOpcode opcode;
|
||||
int short_pic_num; ///< pic_num without wrapping (pic_num & max_pic_num)
|
||||
int long_arg; ///< index, pic_num, or num long refs depending on opcode
|
||||
} MMCO;
|
||||
|
||||
/**
|
||||
* H264Context
|
||||
*/
|
||||
typedef struct H264Context{
|
||||
MpegEncContext s;
|
||||
int nal_ref_idc;
|
||||
int nal_unit_type;
|
||||
uint8_t *rbsp_buffer[2];
|
||||
unsigned int rbsp_buffer_size[2];
|
||||
|
||||
/**
|
||||
* Used to parse AVC variant of h264
|
||||
*/
|
||||
int is_avc; ///< this flag is != 0 if codec is avc1
|
||||
int got_avcC; ///< flag used to parse avcC data only once
|
||||
int nal_length_size; ///< Number of bytes used for nal length (1, 2 or 4)
|
||||
|
||||
int chroma_qp[2]; //QPc
|
||||
|
||||
int prev_mb_skipped;
|
||||
int next_mb_skipped;
|
||||
|
||||
//prediction stuff
|
||||
int chroma_pred_mode;
|
||||
int intra16x16_pred_mode;
|
||||
|
||||
int top_mb_xy;
|
||||
int left_mb_xy[2];
|
||||
|
||||
int8_t intra4x4_pred_mode_cache[5*8];
|
||||
int8_t (*intra4x4_pred_mode)[8];
|
||||
H264PredContext hpc;
|
||||
unsigned int topleft_samples_available;
|
||||
unsigned int top_samples_available;
|
||||
unsigned int topright_samples_available;
|
||||
unsigned int left_samples_available;
|
||||
uint8_t (*top_borders[2])[16+2*8];
|
||||
uint8_t left_border[2*(17+2*9)];
|
||||
|
||||
/**
|
||||
* non zero coeff count cache.
|
||||
* is 64 if not available.
|
||||
*/
|
||||
DECLARE_ALIGNED_8(uint8_t, non_zero_count_cache[6*8]);
|
||||
uint8_t (*non_zero_count)[16];
|
||||
|
||||
/**
|
||||
* Motion vector cache.
|
||||
*/
|
||||
DECLARE_ALIGNED_8(int16_t, mv_cache[2][5*8][2]);
|
||||
DECLARE_ALIGNED_8(int8_t, ref_cache[2][5*8]);
|
||||
#define LIST_NOT_USED -1 //FIXME rename?
|
||||
#define PART_NOT_AVAILABLE -2
|
||||
|
||||
/**
|
||||
* is 1 if the specific list MV&references are set to 0,0,-2.
|
||||
*/
|
||||
int mv_cache_clean[2];
|
||||
|
||||
/**
|
||||
* number of neighbors (top and/or left) that used 8x8 dct
|
||||
*/
|
||||
int neighbor_transform_size;
|
||||
|
||||
/**
|
||||
* block_offset[ 0..23] for frame macroblocks
|
||||
* block_offset[24..47] for field macroblocks
|
||||
*/
|
||||
int block_offset[2*(16+8)];
|
||||
|
||||
uint32_t *mb2b_xy; //FIXME are these 4 a good idea?
|
||||
uint32_t *mb2b8_xy;
|
||||
int b_stride; //FIXME use s->b4_stride
|
||||
int b8_stride;
|
||||
|
||||
int mb_linesize; ///< may be equal to s->linesize or s->linesize*2, for mbaff
|
||||
int mb_uvlinesize;
|
||||
|
||||
int emu_edge_width;
|
||||
int emu_edge_height;
|
||||
|
||||
int halfpel_flag;
|
||||
int thirdpel_flag;
|
||||
|
||||
int unknown_svq3_flag;
|
||||
int next_slice_index;
|
||||
|
||||
SPS *sps_buffers[MAX_SPS_COUNT];
|
||||
SPS sps; ///< current sps
|
||||
|
||||
PPS *pps_buffers[MAX_PPS_COUNT];
|
||||
/**
|
||||
* current pps
|
||||
*/
|
||||
PPS pps; //FIXME move to Picture perhaps? (->no) do we need that?
|
||||
|
||||
uint32_t dequant4_buffer[6][52][16];
|
||||
uint32_t dequant8_buffer[2][52][64];
|
||||
uint32_t (*dequant4_coeff[6])[16];
|
||||
uint32_t (*dequant8_coeff[2])[64];
|
||||
int dequant_coeff_pps; ///< reinit tables when pps changes
|
||||
|
||||
int slice_num;
|
||||
uint8_t *slice_table_base;
|
||||
uint8_t *slice_table; ///< slice_table_base + 2*mb_stride + 1
|
||||
int slice_type;
|
||||
int slice_type_nos; ///< S free slice type (SI/SP are remapped to I/P)
|
||||
int slice_type_fixed;
|
||||
|
||||
//interlacing specific flags
|
||||
int mb_aff_frame;
|
||||
int mb_field_decoding_flag;
|
||||
int mb_mbaff; ///< mb_aff_frame && mb_field_decoding_flag
|
||||
|
||||
unsigned int sub_mb_type[4];
|
||||
|
||||
//POC stuff
|
||||
int poc_lsb;
|
||||
int poc_msb;
|
||||
int delta_poc_bottom;
|
||||
int delta_poc[2];
|
||||
int frame_num;
|
||||
int prev_poc_msb; ///< poc_msb of the last reference pic for POC type 0
|
||||
int prev_poc_lsb; ///< poc_lsb of the last reference pic for POC type 0
|
||||
int frame_num_offset; ///< for POC type 2
|
||||
int prev_frame_num_offset; ///< for POC type 2
|
||||
int prev_frame_num; ///< frame_num of the last pic for POC type 1/2
|
||||
|
||||
/**
|
||||
* frame_num for frames or 2*frame_num+1 for field pics.
|
||||
*/
|
||||
int curr_pic_num;
|
||||
|
||||
/**
|
||||
* max_frame_num or 2*max_frame_num for field pics.
|
||||
*/
|
||||
int max_pic_num;
|
||||
|
||||
//Weighted pred stuff
|
||||
int use_weight;
|
||||
int use_weight_chroma;
|
||||
int luma_log2_weight_denom;
|
||||
int chroma_log2_weight_denom;
|
||||
int luma_weight[2][48];
|
||||
int luma_offset[2][48];
|
||||
int chroma_weight[2][48][2];
|
||||
int chroma_offset[2][48][2];
|
||||
int implicit_weight[48][48];
|
||||
|
||||
//deblock
|
||||
int deblocking_filter; ///< disable_deblocking_filter_idc with 1<->0
|
||||
int slice_alpha_c0_offset;
|
||||
int slice_beta_offset;
|
||||
|
||||
int redundant_pic_count;
|
||||
|
||||
int direct_spatial_mv_pred;
|
||||
int dist_scale_factor[16];
|
||||
int dist_scale_factor_field[32];
|
||||
int map_col_to_list0[2][16];
|
||||
int map_col_to_list0_field[2][32];
|
||||
|
||||
/**
|
||||
* num_ref_idx_l0/1_active_minus1 + 1
|
||||
*/
|
||||
unsigned int ref_count[2]; ///< counts frames or fields, depending on current mb mode
|
||||
unsigned int list_count;
|
||||
Picture *short_ref[32];
|
||||
Picture *long_ref[32];
|
||||
Picture default_ref_list[2][32]; ///< base reference list for all slices of a coded picture
|
||||
Picture ref_list[2][48]; /**< 0..15: frame refs, 16..47: mbaff field refs.
|
||||
Reordered version of default_ref_list
|
||||
according to picture reordering in slice header */
|
||||
int ref2frm[16][2][64]; ///< reference to frame number lists, used in the loop filter, the first 2 are for -2,-1
|
||||
Picture *delayed_pic[MAX_DELAYED_PIC_COUNT+2]; //FIXME size?
|
||||
int outputed_poc;
|
||||
|
||||
/**
|
||||
* memory management control operations buffer.
|
||||
*/
|
||||
MMCO mmco[MAX_MMCO_COUNT];
|
||||
int mmco_index;
|
||||
|
||||
int long_ref_count; ///< number of actual long term references
|
||||
int short_ref_count; ///< number of actual short term references
|
||||
|
||||
//data partitioning
|
||||
GetBitContext intra_gb;
|
||||
GetBitContext inter_gb;
|
||||
GetBitContext *intra_gb_ptr;
|
||||
GetBitContext *inter_gb_ptr;
|
||||
|
||||
DECLARE_ALIGNED_16(DCTELEM, mb[16*24]);
|
||||
DCTELEM mb_padding[256]; ///< as mb is addressed by scantable[i] and scantable is uint8_t we can either check that i is not too large or ensure that there is some unused stuff after mb
|
||||
|
||||
/**
|
||||
* Cabac
|
||||
*/
|
||||
CABACContext cabac;
|
||||
uint8_t cabac_state[460];
|
||||
int cabac_init_idc;
|
||||
|
||||
/* 0x100 -> non null luma_dc, 0x80/0x40 -> non null chroma_dc (cb/cr), 0x?0 -> chroma_cbp(0,1,2), 0x0? luma_cbp */
|
||||
uint16_t *cbp_table;
|
||||
int cbp;
|
||||
int top_cbp;
|
||||
int left_cbp;
|
||||
/* chroma_pred_mode for i4x4 or i16x16, else 0 */
|
||||
uint8_t *chroma_pred_mode_table;
|
||||
int last_qscale_diff;
|
||||
int16_t (*mvd_table[2])[2];
|
||||
DECLARE_ALIGNED_8(int16_t, mvd_cache[2][5*8][2]);
|
||||
uint8_t *direct_table;
|
||||
uint8_t direct_cache[5*8];
|
||||
|
||||
uint8_t zigzag_scan[16];
|
||||
uint8_t zigzag_scan8x8[64];
|
||||
uint8_t zigzag_scan8x8_cavlc[64];
|
||||
uint8_t field_scan[16];
|
||||
uint8_t field_scan8x8[64];
|
||||
uint8_t field_scan8x8_cavlc[64];
|
||||
const uint8_t *zigzag_scan_q0;
|
||||
const uint8_t *zigzag_scan8x8_q0;
|
||||
const uint8_t *zigzag_scan8x8_cavlc_q0;
|
||||
const uint8_t *field_scan_q0;
|
||||
const uint8_t *field_scan8x8_q0;
|
||||
const uint8_t *field_scan8x8_cavlc_q0;
|
||||
|
||||
int x264_build;
|
||||
|
||||
/**
|
||||
* @defgroup multithreading Members for slice based multithreading
|
||||
* @{
|
||||
*/
|
||||
struct H264Context *thread_context[MAX_THREADS];
|
||||
|
||||
/**
|
||||
* current slice number, used to initalize slice_num of each thread/context
|
||||
*/
|
||||
int current_slice;
|
||||
|
||||
/**
|
||||
* Max number of threads / contexts.
|
||||
* This is equal to AVCodecContext.thread_count unless
|
||||
* multithreaded decoding is impossible, in which case it is
|
||||
* reduced to 1.
|
||||
*/
|
||||
int max_contexts;
|
||||
|
||||
/**
|
||||
* 1 if the single thread fallback warning has already been
|
||||
* displayed, 0 otherwise.
|
||||
*/
|
||||
int single_decode_warning;
|
||||
|
||||
int last_slice_type;
|
||||
/** @} */
|
||||
|
||||
int mb_xy;
|
||||
|
||||
}H264Context;
|
||||
|
||||
#endif /* FFMPEG_H264_H */
|
@ -0,0 +1,154 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Benoit Fouet <benoit.fouet@purplelabs.com>
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg 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,
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "avcodec.h"
|
||||
|
||||
typedef struct H264BSFContext {
|
||||
uint8_t length_size;
|
||||
uint8_t first_idr;
|
||||
uint8_t *sps_pps_data;
|
||||
uint32_t size;
|
||||
} H264BSFContext;
|
||||
|
||||
static void alloc_and_copy(uint8_t **poutbuf, int *poutbuf_size,
|
||||
const uint8_t *sps_pps, uint32_t sps_pps_size,
|
||||
const uint8_t *in, uint32_t in_size) {
|
||||
uint32_t offset = *poutbuf_size;
|
||||
uint8_t nal_header_size = offset ? 3 : 4;
|
||||
|
||||
*poutbuf_size += sps_pps_size+in_size+nal_header_size;
|
||||
*poutbuf = av_realloc(*poutbuf, *poutbuf_size);
|
||||
if (sps_pps)
|
||||
memcpy(*poutbuf+offset, sps_pps, sps_pps_size);
|
||||
memcpy(*poutbuf+sps_pps_size+nal_header_size+offset, in, in_size);
|
||||
if (!offset)
|
||||
AV_WB32(*poutbuf+sps_pps_size, 1);
|
||||
else {
|
||||
(*poutbuf+offset+sps_pps_size)[0] = (*poutbuf+offset+sps_pps_size)[1] = 0;
|
||||
(*poutbuf+offset+sps_pps_size)[2] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static int h264_mp4toannexb_filter(AVBitStreamFilterContext *bsfc,
|
||||
AVCodecContext *avctx, const char *args,
|
||||
uint8_t **poutbuf, int *poutbuf_size,
|
||||
const uint8_t *buf, int buf_size,
|
||||
int keyframe) {
|
||||
H264BSFContext *ctx = bsfc->priv_data;
|
||||
uint8_t unit_type;
|
||||
uint32_t nal_size, cumul_size = 0;
|
||||
|
||||
/* nothing to filter */
|
||||
if (!avctx->extradata || avctx->extradata_size < 6) {
|
||||
*poutbuf = (uint8_t*) buf;
|
||||
*poutbuf_size = buf_size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* retrieve sps and pps NAL units from extradata */
|
||||
if (!ctx->sps_pps_data) {
|
||||
uint16_t unit_size;
|
||||
uint32_t total_size = 0;
|
||||
uint8_t *out = NULL, unit_nb, sps_done = 0;
|
||||
const uint8_t *extradata = avctx->extradata+4;
|
||||
static const uint8_t nalu_header[4] = {0, 0, 0, 1};
|
||||
|
||||
/* retrieve length coded size */
|
||||
ctx->length_size = (*extradata++ & 0x3) + 1;
|
||||
if (ctx->length_size == 3)
|
||||
return AVERROR(EINVAL);
|
||||
|
||||
/* retrieve sps and pps unit(s) */
|
||||
unit_nb = *extradata++ & 0x1f; /* number of sps unit(s) */
|
||||
if (!unit_nb) {
|
||||
unit_nb = *extradata++; /* number of pps unit(s) */
|
||||
sps_done++;
|
||||
}
|
||||
while (unit_nb--) {
|
||||
unit_size = AV_RB16(extradata);
|
||||
total_size += unit_size+4;
|
||||
if (extradata+2+unit_size > avctx->extradata+avctx->extradata_size) {
|
||||
av_free(out);
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
out = av_realloc(out, total_size);
|
||||
if (!out)
|
||||
return AVERROR(ENOMEM);
|
||||
memcpy(out+total_size-unit_size-4, nalu_header, 4);
|
||||
memcpy(out+total_size-unit_size, extradata+2, unit_size);
|
||||
extradata += 2+unit_size;
|
||||
|
||||
if (!unit_nb && !sps_done++)
|
||||
unit_nb = *extradata++; /* number of pps unit(s) */
|
||||
}
|
||||
|
||||
ctx->sps_pps_data = out;
|
||||
ctx->size = total_size;
|
||||
ctx->first_idr = 1;
|
||||
}
|
||||
|
||||
*poutbuf_size = 0;
|
||||
*poutbuf = NULL;
|
||||
do {
|
||||
if (ctx->length_size == 1)
|
||||
nal_size = buf[0];
|
||||
else if (ctx->length_size == 2)
|
||||
nal_size = AV_RB16(buf);
|
||||
else
|
||||
nal_size = AV_RB32(buf);
|
||||
|
||||
buf += ctx->length_size;
|
||||
unit_type = *buf & 0x1f;
|
||||
|
||||
/* prepend only to the first type 5 NAL unit of an IDR picture */
|
||||
if (ctx->first_idr && unit_type == 5) {
|
||||
alloc_and_copy(poutbuf, poutbuf_size,
|
||||
ctx->sps_pps_data, ctx->size,
|
||||
buf, nal_size);
|
||||
ctx->first_idr = 0;
|
||||
}
|
||||
else {
|
||||
alloc_and_copy(poutbuf, poutbuf_size,
|
||||
NULL, 0,
|
||||
buf, nal_size);
|
||||
if (!ctx->first_idr && unit_type == 1)
|
||||
ctx->first_idr = 1;
|
||||
}
|
||||
|
||||
buf += nal_size;
|
||||
cumul_size += nal_size + ctx->length_size;
|
||||
} while (cumul_size < buf_size);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void h264_mp4toannexb_close(AVBitStreamFilterContext *bsfc)
|
||||
{
|
||||
H264BSFContext *ctx = bsfc->priv_data;
|
||||
av_freep(&ctx->sps_pps_data);
|
||||
}
|
||||
|
||||
AVBitStreamFilter h264_mp4toannexb_bsf = {
|
||||
"h264_mp4toannexb",
|
||||
sizeof(H264BSFContext),
|
||||
h264_mp4toannexb_filter,
|
||||
h264_mp4toannexb_close,
|
||||
};
|
||||
|
148
src/add-ons/media/plugins/avcodec/libavcodec/h264_parser.c
Normal file
148
src/add-ons/media/plugins/avcodec/libavcodec/h264_parser.c
Normal file
@ -0,0 +1,148 @@
|
||||
/*
|
||||
* H.26L/H.264/AVC/JVT/14496-10/... parser
|
||||
* Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg 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,
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file h264_parser.c
|
||||
* H.264 / AVC / MPEG4 part10 parser.
|
||||
* @author Michael Niedermayer <michaelni@gmx.at>
|
||||
*/
|
||||
|
||||
#include "parser.h"
|
||||
#include "h264_parser.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
int ff_h264_find_frame_end(H264Context *h, const uint8_t *buf, int buf_size)
|
||||
{
|
||||
int i;
|
||||
uint32_t state;
|
||||
ParseContext *pc = &(h->s.parse_context);
|
||||
//printf("first %02X%02X%02X%02X\n", buf[0], buf[1],buf[2],buf[3]);
|
||||
// mb_addr= pc->mb_addr - 1;
|
||||
state= pc->state;
|
||||
if(state>13)
|
||||
state= 7;
|
||||
|
||||
for(i=0; i<buf_size; i++){
|
||||
if(state==7){
|
||||
for(; i<buf_size; i++){
|
||||
if(!buf[i]){
|
||||
state=2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}else if(state<=2){
|
||||
if(buf[i]==1) state^= 5; //2->7, 1->4, 0->5
|
||||
else if(buf[i]) state = 7;
|
||||
else state>>=1; //2->1, 1->0, 0->0
|
||||
}else if(state<=5){
|
||||
int v= buf[i] & 0x1F;
|
||||
if(v==7 || v==8 || v==9){
|
||||
if(pc->frame_start_found){
|
||||
i++;
|
||||
found:
|
||||
pc->state=7;
|
||||
pc->frame_start_found= 0;
|
||||
return i-(state&5);
|
||||
}
|
||||
}else if(v==1 || v==2 || v==5){
|
||||
if(pc->frame_start_found){
|
||||
state+=8;
|
||||
continue;
|
||||
}else
|
||||
pc->frame_start_found = 1;
|
||||
}
|
||||
state= 7;
|
||||
}else{
|
||||
if(buf[i] & 0x80)
|
||||
goto found;
|
||||
state= 7;
|
||||
}
|
||||
}
|
||||
pc->state= state;
|
||||
return END_NOT_FOUND;
|
||||
}
|
||||
|
||||
static int h264_parse(AVCodecParserContext *s,
|
||||
AVCodecContext *avctx,
|
||||
const uint8_t **poutbuf, int *poutbuf_size,
|
||||
const uint8_t *buf, int buf_size)
|
||||
{
|
||||
H264Context *h = s->priv_data;
|
||||
ParseContext *pc = &h->s.parse_context;
|
||||
int next;
|
||||
|
||||
if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){
|
||||
next= buf_size;
|
||||
}else{
|
||||
next= ff_h264_find_frame_end(h, buf, buf_size);
|
||||
|
||||
if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
|
||||
*poutbuf = NULL;
|
||||
*poutbuf_size = 0;
|
||||
return buf_size;
|
||||
}
|
||||
|
||||
if(next<0 && next != END_NOT_FOUND){
|
||||
assert(pc->last_index + next >= 0 );
|
||||
ff_h264_find_frame_end(h, &pc->buffer[pc->last_index + next], -next); //update state
|
||||
}
|
||||
}
|
||||
|
||||
*poutbuf = buf;
|
||||
*poutbuf_size = buf_size;
|
||||
return next;
|
||||
}
|
||||
|
||||
static int h264_split(AVCodecContext *avctx,
|
||||
const uint8_t *buf, int buf_size)
|
||||
{
|
||||
int i;
|
||||
uint32_t state = -1;
|
||||
int has_sps= 0;
|
||||
|
||||
for(i=0; i<=buf_size; i++){
|
||||
if((state&0xFFFFFF1F) == 0x107)
|
||||
has_sps=1;
|
||||
/* if((state&0xFFFFFF1F) == 0x101 || (state&0xFFFFFF1F) == 0x102 || (state&0xFFFFFF1F) == 0x105){
|
||||
}*/
|
||||
if((state&0xFFFFFF00) == 0x100 && (state&0xFFFFFF1F) != 0x107 && (state&0xFFFFFF1F) != 0x108 && (state&0xFFFFFF1F) != 0x109){
|
||||
if(has_sps){
|
||||
while(i>4 && buf[i-5]==0) i--;
|
||||
return i-4;
|
||||
}
|
||||
}
|
||||
if (i<buf_size)
|
||||
state= (state<<8) | buf[i];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
AVCodecParser h264_parser = {
|
||||
{ CODEC_ID_H264 },
|
||||
sizeof(H264Context),
|
||||
NULL,
|
||||
h264_parse,
|
||||
ff_parse_close,
|
||||
h264_split,
|
||||
};
|
39
src/add-ons/media/plugins/avcodec/libavcodec/h264_parser.h
Normal file
39
src/add-ons/media/plugins/avcodec/libavcodec/h264_parser.h
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* H.26L/H.264/AVC/JVT/14496-10/... parser
|
||||
* Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg 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,
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file h264_parser.h
|
||||
* H.264 / AVC / MPEG4 part10 parser.
|
||||
* @author Michael Niedermayer <michaelni@gmx.at>
|
||||
*/
|
||||
|
||||
#ifndef FFMPEG_H264_PARSER_H
|
||||
#define FFMPEG_H264_PARSER_H
|
||||
|
||||
#include "h264.h"
|
||||
|
||||
/**
|
||||
* finds the end of the current frame in the bitstream.
|
||||
* @return the position of the first byte of the next frame, or -1
|
||||
*/
|
||||
int ff_h264_find_frame_end(H264Context *h, const uint8_t *buf, int buf_size);
|
||||
|
||||
#endif /* FFMPEG_H264_PARSER_H */
|
File diff suppressed because it is too large
Load Diff
81
src/add-ons/media/plugins/avcodec/libavcodec/h264dspenc.c
Normal file
81
src/add-ons/media/plugins/avcodec/libavcodec/h264dspenc.c
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* H.264/MPEG-4 Part 10 (Base profile) encoder.
|
||||
*
|
||||
* DSP functions
|
||||
*
|
||||
* Copyright (c) 2006 Expertisecentrum Digitale Media, UHasselt
|
||||
*
|
||||
* FFmpeg 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,
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file h264dspenc.c
|
||||
* H.264 encoder related DSP utils
|
||||
*
|
||||
*/
|
||||
|
||||
#include "dsputil.h"
|
||||
|
||||
extern const uint8_t ff_div6[52];
|
||||
extern const uint8_t ff_rem6[52];
|
||||
|
||||
#define H264_DCT_PART1(X) \
|
||||
a = block[0][X]+block[3][X]; \
|
||||
c = block[0][X]-block[3][X]; \
|
||||
b = block[1][X]+block[2][X]; \
|
||||
d = block[1][X]-block[2][X]; \
|
||||
pieces[0][X] = a+b; \
|
||||
pieces[2][X] = a-b; \
|
||||
pieces[1][X] = (c<<1)+d; \
|
||||
pieces[3][X] = c-(d<<1);
|
||||
|
||||
#define H264_DCT_PART2(X) \
|
||||
a = pieces[X][0]+pieces[X][3]; \
|
||||
c = pieces[X][0]-pieces[X][3]; \
|
||||
b = pieces[X][1]+pieces[X][2]; \
|
||||
d = pieces[X][1]-pieces[X][2]; \
|
||||
block[0][X] = a+b; \
|
||||
block[2][X] = a-b; \
|
||||
block[1][X] = (c<<1)+d; \
|
||||
block[3][X] = c-(d<<1);
|
||||
|
||||
/**
|
||||
* Transform the provided matrix using the H.264 modified DCT.
|
||||
* @note
|
||||
* we'll always work with transposed input blocks, to avoid having to make a
|
||||
* distinction between C and mmx implementations.
|
||||
*
|
||||
* @param block transposed input block
|
||||
*/
|
||||
static void h264_dct_c(DCTELEM block[4][4])
|
||||
{
|
||||
DCTELEM pieces[4][4];
|
||||
DCTELEM a, b, c, d;
|
||||
|
||||
H264_DCT_PART1(0);
|
||||
H264_DCT_PART1(1);
|
||||
H264_DCT_PART1(2);
|
||||
H264_DCT_PART1(3);
|
||||
H264_DCT_PART2(0);
|
||||
H264_DCT_PART2(1);
|
||||
H264_DCT_PART2(2);
|
||||
H264_DCT_PART2(3);
|
||||
}
|
||||
|
||||
void ff_h264dspenc_init(DSPContext* c, AVCodecContext *avctx)
|
||||
{
|
||||
c->h264_dct = h264_dct_c;
|
||||
}
|
||||
|
107
src/add-ons/media/plugins/avcodec/libavcodec/h264enc.c
Normal file
107
src/add-ons/media/plugins/avcodec/libavcodec/h264enc.c
Normal file
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* H.264 encoder
|
||||
*
|
||||
* FFmpeg 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,
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
|
||||
#include "libavutil/common.h"
|
||||
#include "bitstream.h"
|
||||
#include "mpegvideo.h"
|
||||
#include "h264data.h"
|
||||
|
||||
/**
|
||||
* Write out the provided data into a NAL unit.
|
||||
* @param nal_ref_idc NAL reference IDC
|
||||
* @param nal_unit_type NAL unit payload type
|
||||
* @param dest the target buffer, dst+1 == src is allowed as a special case
|
||||
* @param destsize the length of the dst array
|
||||
* @param b2 the data which should be escaped
|
||||
* @returns pointer to current position in the output buffer or NULL if an error occurred
|
||||
*/
|
||||
static uint8_t *h264_write_nal_unit(int nal_ref_idc, int nal_unit_type, uint8_t *dest, int *destsize,
|
||||
PutBitContext *b2)
|
||||
{
|
||||
PutBitContext b;
|
||||
int i, destpos, rbsplen, escape_count;
|
||||
uint8_t *rbsp;
|
||||
|
||||
if (nal_unit_type != NAL_END_STREAM)
|
||||
put_bits(b2,1,1); // rbsp_stop_bit
|
||||
|
||||
// Align b2 on a byte boundary
|
||||
align_put_bits(b2);
|
||||
rbsplen = put_bits_count(b2)/8;
|
||||
flush_put_bits(b2);
|
||||
rbsp = b2->buf;
|
||||
|
||||
init_put_bits(&b,dest,*destsize);
|
||||
|
||||
put_bits(&b,16,0);
|
||||
put_bits(&b,16,0x01);
|
||||
|
||||
put_bits(&b,1,0); // forbidden zero bit
|
||||
put_bits(&b,2,nal_ref_idc); // nal_ref_idc
|
||||
put_bits(&b,5,nal_unit_type); // nal_unit_type
|
||||
|
||||
flush_put_bits(&b);
|
||||
|
||||
destpos = 5;
|
||||
escape_count= 0;
|
||||
|
||||
for (i=0; i<rbsplen; i+=2)
|
||||
{
|
||||
if (rbsp[i]) continue;
|
||||
if (i>0 && rbsp[i-1]==0)
|
||||
i--;
|
||||
if (i+2<rbsplen && rbsp[i+1]==0 && rbsp[i+2]<=3)
|
||||
{
|
||||
escape_count++;
|
||||
i+=2;
|
||||
}
|
||||
}
|
||||
|
||||
if(escape_count==0)
|
||||
{
|
||||
if(dest+destpos != rbsp)
|
||||
{
|
||||
memcpy(dest+destpos, rbsp, rbsplen);
|
||||
*destsize -= (rbsplen+destpos);
|
||||
}
|
||||
return dest+rbsplen+destpos;
|
||||
}
|
||||
|
||||
if(rbsplen + escape_count + 1> *destsize)
|
||||
{
|
||||
av_log(NULL, AV_LOG_ERROR, "Destination buffer too small!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// this should be damn rare (hopefully)
|
||||
for (i = 0 ; i < rbsplen ; i++)
|
||||
{
|
||||
if (i + 2 < rbsplen && (rbsp[i] == 0 && rbsp[i+1] == 0 && rbsp[i+2] < 4))
|
||||
{
|
||||
dest[destpos++] = rbsp[i++];
|
||||
dest[destpos++] = rbsp[i];
|
||||
dest[destpos++] = 0x03; // emulation prevention byte
|
||||
}
|
||||
else
|
||||
dest[destpos++] = rbsp[i];
|
||||
}
|
||||
*destsize -= destpos;
|
||||
return dest+destpos;
|
||||
}
|
||||
|
167
src/add-ons/media/plugins/avcodec/libavcodec/h264idct.c
Normal file
167
src/add-ons/media/plugins/avcodec/libavcodec/h264idct.c
Normal file
@ -0,0 +1,167 @@
|
||||
/*
|
||||
* H.264 IDCT
|
||||
* Copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg 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,
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file h264-idct.c
|
||||
* H.264 IDCT.
|
||||
* @author Michael Niedermayer <michaelni@gmx.at>
|
||||
*/
|
||||
|
||||
#include "dsputil.h"
|
||||
|
||||
static av_always_inline void idct_internal(uint8_t *dst, DCTELEM *block, int stride, int block_stride, int shift, int add){
|
||||
int i;
|
||||
uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
|
||||
|
||||
block[0] += 1<<(shift-1);
|
||||
|
||||
for(i=0; i<4; i++){
|
||||
const int z0= block[0 + block_stride*i] + block[2 + block_stride*i];
|
||||
const int z1= block[0 + block_stride*i] - block[2 + block_stride*i];
|
||||
const int z2= (block[1 + block_stride*i]>>1) - block[3 + block_stride*i];
|
||||
const int z3= block[1 + block_stride*i] + (block[3 + block_stride*i]>>1);
|
||||
|
||||
block[0 + block_stride*i]= z0 + z3;
|
||||
block[1 + block_stride*i]= z1 + z2;
|
||||
block[2 + block_stride*i]= z1 - z2;
|
||||
block[3 + block_stride*i]= z0 - z3;
|
||||
}
|
||||
|
||||
for(i=0; i<4; i++){
|
||||
const int z0= block[i + block_stride*0] + block[i + block_stride*2];
|
||||
const int z1= block[i + block_stride*0] - block[i + block_stride*2];
|
||||
const int z2= (block[i + block_stride*1]>>1) - block[i + block_stride*3];
|
||||
const int z3= block[i + block_stride*1] + (block[i + block_stride*3]>>1);
|
||||
|
||||
dst[i + 0*stride]= cm[ add*dst[i + 0*stride] + ((z0 + z3) >> shift) ];
|
||||
dst[i + 1*stride]= cm[ add*dst[i + 1*stride] + ((z1 + z2) >> shift) ];
|
||||
dst[i + 2*stride]= cm[ add*dst[i + 2*stride] + ((z1 - z2) >> shift) ];
|
||||
dst[i + 3*stride]= cm[ add*dst[i + 3*stride] + ((z0 - z3) >> shift) ];
|
||||
}
|
||||
}
|
||||
|
||||
void ff_h264_idct_add_c(uint8_t *dst, DCTELEM *block, int stride){
|
||||
idct_internal(dst, block, stride, 4, 6, 1);
|
||||
}
|
||||
|
||||
void ff_h264_lowres_idct_add_c(uint8_t *dst, int stride, DCTELEM *block){
|
||||
idct_internal(dst, block, stride, 8, 3, 1);
|
||||
}
|
||||
|
||||
void ff_h264_lowres_idct_put_c(uint8_t *dst, int stride, DCTELEM *block){
|
||||
idct_internal(dst, block, stride, 8, 3, 0);
|
||||
}
|
||||
|
||||
void ff_h264_idct8_add_c(uint8_t *dst, DCTELEM *block, int stride){
|
||||
int i;
|
||||
DCTELEM (*src)[8] = (DCTELEM(*)[8])block;
|
||||
uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
|
||||
|
||||
block[0] += 32;
|
||||
|
||||
for( i = 0; i < 8; i++ )
|
||||
{
|
||||
const int a0 = src[i][0] + src[i][4];
|
||||
const int a2 = src[i][0] - src[i][4];
|
||||
const int a4 = (src[i][2]>>1) - src[i][6];
|
||||
const int a6 = (src[i][6]>>1) + src[i][2];
|
||||
|
||||
const int b0 = a0 + a6;
|
||||
const int b2 = a2 + a4;
|
||||
const int b4 = a2 - a4;
|
||||
const int b6 = a0 - a6;
|
||||
|
||||
const int a1 = -src[i][3] + src[i][5] - src[i][7] - (src[i][7]>>1);
|
||||
const int a3 = src[i][1] + src[i][7] - src[i][3] - (src[i][3]>>1);
|
||||
const int a5 = -src[i][1] + src[i][7] + src[i][5] + (src[i][5]>>1);
|
||||
const int a7 = src[i][3] + src[i][5] + src[i][1] + (src[i][1]>>1);
|
||||
|
||||
const int b1 = (a7>>2) + a1;
|
||||
const int b3 = a3 + (a5>>2);
|
||||
const int b5 = (a3>>2) - a5;
|
||||
const int b7 = a7 - (a1>>2);
|
||||
|
||||
src[i][0] = b0 + b7;
|
||||
src[i][7] = b0 - b7;
|
||||
src[i][1] = b2 + b5;
|
||||
src[i][6] = b2 - b5;
|
||||
src[i][2] = b4 + b3;
|
||||
src[i][5] = b4 - b3;
|
||||
src[i][3] = b6 + b1;
|
||||
src[i][4] = b6 - b1;
|
||||
}
|
||||
for( i = 0; i < 8; i++ )
|
||||
{
|
||||
const int a0 = src[0][i] + src[4][i];
|
||||
const int a2 = src[0][i] - src[4][i];
|
||||
const int a4 = (src[2][i]>>1) - src[6][i];
|
||||
const int a6 = (src[6][i]>>1) + src[2][i];
|
||||
|
||||
const int b0 = a0 + a6;
|
||||
const int b2 = a2 + a4;
|
||||
const int b4 = a2 - a4;
|
||||
const int b6 = a0 - a6;
|
||||
|
||||
const int a1 = -src[3][i] + src[5][i] - src[7][i] - (src[7][i]>>1);
|
||||
const int a3 = src[1][i] + src[7][i] - src[3][i] - (src[3][i]>>1);
|
||||
const int a5 = -src[1][i] + src[7][i] + src[5][i] + (src[5][i]>>1);
|
||||
const int a7 = src[3][i] + src[5][i] + src[1][i] + (src[1][i]>>1);
|
||||
|
||||
const int b1 = (a7>>2) + a1;
|
||||
const int b3 = a3 + (a5>>2);
|
||||
const int b5 = (a3>>2) - a5;
|
||||
const int b7 = a7 - (a1>>2);
|
||||
|
||||
dst[i + 0*stride] = cm[ dst[i + 0*stride] + ((b0 + b7) >> 6) ];
|
||||
dst[i + 1*stride] = cm[ dst[i + 1*stride] + ((b2 + b5) >> 6) ];
|
||||
dst[i + 2*stride] = cm[ dst[i + 2*stride] + ((b4 + b3) >> 6) ];
|
||||
dst[i + 3*stride] = cm[ dst[i + 3*stride] + ((b6 + b1) >> 6) ];
|
||||
dst[i + 4*stride] = cm[ dst[i + 4*stride] + ((b6 - b1) >> 6) ];
|
||||
dst[i + 5*stride] = cm[ dst[i + 5*stride] + ((b4 - b3) >> 6) ];
|
||||
dst[i + 6*stride] = cm[ dst[i + 6*stride] + ((b2 - b5) >> 6) ];
|
||||
dst[i + 7*stride] = cm[ dst[i + 7*stride] + ((b0 - b7) >> 6) ];
|
||||
}
|
||||
}
|
||||
|
||||
// assumes all AC coefs are 0
|
||||
void ff_h264_idct_dc_add_c(uint8_t *dst, DCTELEM *block, int stride){
|
||||
int i, j;
|
||||
uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
|
||||
int dc = (block[0] + 32) >> 6;
|
||||
for( j = 0; j < 4; j++ )
|
||||
{
|
||||
for( i = 0; i < 4; i++ )
|
||||
dst[i] = cm[ dst[i] + dc ];
|
||||
dst += stride;
|
||||
}
|
||||
}
|
||||
|
||||
void ff_h264_idct8_dc_add_c(uint8_t *dst, DCTELEM *block, int stride){
|
||||
int i, j;
|
||||
uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
|
||||
int dc = (block[0] + 32) >> 6;
|
||||
for( j = 0; j < 8; j++ )
|
||||
{
|
||||
for( i = 0; i < 8; i++ )
|
||||
dst[i] = cm[ dst[i] + dc ];
|
||||
dst += stride;
|
||||
}
|
||||
}
|
1100
src/add-ons/media/plugins/avcodec/libavcodec/h264pred.c
Normal file
1100
src/add-ons/media/plugins/avcodec/libavcodec/h264pred.c
Normal file
File diff suppressed because it is too large
Load Diff
82
src/add-ons/media/plugins/avcodec/libavcodec/h264pred.h
Normal file
82
src/add-ons/media/plugins/avcodec/libavcodec/h264pred.h
Normal file
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder
|
||||
* Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg 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,
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file h264pred.h
|
||||
* H.264 / AVC / MPEG4 prediction functions.
|
||||
* @author Michael Niedermayer <michaelni@gmx.at>
|
||||
*/
|
||||
|
||||
#ifndef FFMPEG_H264PRED_H
|
||||
#define FFMPEG_H264PRED_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
/**
|
||||
* Prediction types
|
||||
*/
|
||||
//@{
|
||||
#define VERT_PRED 0
|
||||
#define HOR_PRED 1
|
||||
#define DC_PRED 2
|
||||
#define DIAG_DOWN_LEFT_PRED 3
|
||||
#define DIAG_DOWN_RIGHT_PRED 4
|
||||
#define VERT_RIGHT_PRED 5
|
||||
#define HOR_DOWN_PRED 6
|
||||
#define VERT_LEFT_PRED 7
|
||||
#define HOR_UP_PRED 8
|
||||
|
||||
#define LEFT_DC_PRED 9
|
||||
#define TOP_DC_PRED 10
|
||||
#define DC_128_PRED 11
|
||||
|
||||
#define DIAG_DOWN_LEFT_PRED_RV40_NODOWN 12
|
||||
#define HOR_UP_PRED_RV40_NODOWN 13
|
||||
#define VERT_LEFT_PRED_RV40_NODOWN 14
|
||||
|
||||
#define DC_PRED8x8 0
|
||||
#define HOR_PRED8x8 1
|
||||
#define VERT_PRED8x8 2
|
||||
#define PLANE_PRED8x8 3
|
||||
|
||||
#define LEFT_DC_PRED8x8 4
|
||||
#define TOP_DC_PRED8x8 5
|
||||
#define DC_128_PRED8x8 6
|
||||
|
||||
#define ALZHEIMER_DC_L0T_PRED8x8 7
|
||||
#define ALZHEIMER_DC_0LT_PRED8x8 8
|
||||
#define ALZHEIMER_DC_L00_PRED8x8 9
|
||||
#define ALZHEIMER_DC_0L0_PRED8x8 10
|
||||
//@}
|
||||
|
||||
/**
|
||||
* Context for storing H.264 prediction functions
|
||||
*/
|
||||
typedef struct H264PredContext{
|
||||
void (*pred4x4 [9+3+3])(uint8_t *src, uint8_t *topright, int stride);//FIXME move to dsp?
|
||||
void (*pred8x8l [9+3])(uint8_t *src, int topleft, int topright, int stride);
|
||||
void (*pred8x8 [4+3+4])(uint8_t *src, int stride);
|
||||
void (*pred16x16[4+3])(uint8_t *src, int stride);
|
||||
}H264PredContext;
|
||||
|
||||
void ff_h264_pred_init(H264PredContext *h, int codec_id);
|
||||
|
||||
#endif /* FFMPEG_H264PRED_H */
|
109
src/add-ons/media/plugins/avcodec/libavcodec/huffman.c
Normal file
109
src/add-ons/media/plugins/avcodec/libavcodec/huffman.c
Normal file
@ -0,0 +1,109 @@
|
||||
/**
|
||||
* @file huffman.c
|
||||
* huffman tree builder and VLC generator
|
||||
* Copyright (c) 2006 Konstantin Shishkov
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg 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,
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "avcodec.h"
|
||||
#include "bitstream.h"
|
||||
#include "huffman.h"
|
||||
|
||||
/* symbol for Huffman tree node */
|
||||
#define HNODE -1
|
||||
|
||||
|
||||
static void get_tree_codes(uint32_t *bits, int16_t *lens, uint8_t *xlat, Node *nodes, int node, uint32_t pfx, int pl, int *pos, int no_zero_count)
|
||||
{
|
||||
int s;
|
||||
|
||||
s = nodes[node].sym;
|
||||
if(s != HNODE || (no_zero_count && !nodes[node].count)){
|
||||
bits[*pos] = pfx;
|
||||
lens[*pos] = pl;
|
||||
xlat[*pos] = s;
|
||||
(*pos)++;
|
||||
}else{
|
||||
pfx <<= 1;
|
||||
pl++;
|
||||
get_tree_codes(bits, lens, xlat, nodes, nodes[node].n0, pfx, pl, pos,
|
||||
no_zero_count);
|
||||
pfx |= 1;
|
||||
get_tree_codes(bits, lens, xlat, nodes, nodes[node].n0+1, pfx, pl, pos,
|
||||
no_zero_count);
|
||||
}
|
||||
}
|
||||
|
||||
static int build_huff_tree(VLC *vlc, Node *nodes, int head, int flags)
|
||||
{
|
||||
int no_zero_count = !(flags & FF_HUFFMAN_FLAG_ZERO_COUNT);
|
||||
uint32_t bits[256];
|
||||
int16_t lens[256];
|
||||
uint8_t xlat[256];
|
||||
int pos = 0;
|
||||
|
||||
get_tree_codes(bits, lens, xlat, nodes, head, 0, 0, &pos, no_zero_count);
|
||||
return init_vlc_sparse(vlc, 9, pos, lens, 2, 2, bits, 4, 4, xlat, 1, 1, 0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* nodes size must be 2*nb_codes
|
||||
* first nb_codes nodes.count must be set
|
||||
*/
|
||||
int ff_huff_build_tree(AVCodecContext *avctx, VLC *vlc, int nb_codes,
|
||||
Node *nodes, huff_cmp_t cmp, int flags)
|
||||
{
|
||||
int i, j;
|
||||
int cur_node;
|
||||
int64_t sum = 0;
|
||||
|
||||
for(i = 0; i < nb_codes; i++){
|
||||
nodes[i].sym = i;
|
||||
nodes[i].n0 = -2;
|
||||
sum += nodes[i].count;
|
||||
}
|
||||
|
||||
if(sum >> 31) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Too high symbol frequencies. Tree construction is not possible\n");
|
||||
return -1;
|
||||
}
|
||||
qsort(nodes, nb_codes, sizeof(Node), cmp);
|
||||
cur_node = nb_codes;
|
||||
nodes[nb_codes*2-1].count = 0;
|
||||
for(i = 0; i < nb_codes*2-1; i += 2){
|
||||
nodes[cur_node].sym = HNODE;
|
||||
nodes[cur_node].count = nodes[i].count + nodes[i+1].count;
|
||||
nodes[cur_node].n0 = i;
|
||||
for(j = cur_node; j > 0; j--){
|
||||
if(nodes[j].count > nodes[j-1].count ||
|
||||
(nodes[j].count == nodes[j-1].count &&
|
||||
(!(flags & FF_HUFFMAN_FLAG_HNODE_FIRST) ||
|
||||
nodes[j].n0==j-1 || nodes[j].n0==j-2 ||
|
||||
(nodes[j].sym!=HNODE && nodes[j-1].sym!=HNODE))))
|
||||
break;
|
||||
FFSWAP(Node, nodes[j], nodes[j-1]);
|
||||
}
|
||||
cur_node++;
|
||||
}
|
||||
if(build_huff_tree(vlc, nodes, nb_codes*2-2, flags) < 0){
|
||||
av_log(avctx, AV_LOG_ERROR, "Error building tree\n");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
42
src/add-ons/media/plugins/avcodec/libavcodec/huffman.h
Normal file
42
src/add-ons/media/plugins/avcodec/libavcodec/huffman.h
Normal file
@ -0,0 +1,42 @@
|
||||
/**
|
||||
* @file huffman.h
|
||||
* huffman tree builder and VLC generator
|
||||
* Copyright (C) 2007 Aurelien Jacobs <aurel@gnuage.org>
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg 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,
|
||||
* 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
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef FFMPEG_HUFFMAN_H
|
||||
#define FFMPEG_HUFFMAN_H
|
||||
|
||||
#include "avcodec.h"
|
||||
#include "bitstream.h"
|
||||
|
||||
typedef struct {
|
||||
int16_t sym;
|
||||
int16_t n0;
|
||||
uint32_t count;
|
||||
} Node;
|
||||
|
||||
#define FF_HUFFMAN_FLAG_HNODE_FIRST 0x01
|
||||
#define FF_HUFFMAN_FLAG_ZERO_COUNT 0x02
|
||||
|
||||
typedef int (*huff_cmp_t)(const void *va, const void *vb);
|
||||
int ff_huff_build_tree(AVCodecContext *avctx, VLC *vlc, int nb_codes,
|
||||
Node *nodes, huff_cmp_t cmp, int flags);
|
||||
|
||||
#endif /* FFMPEG_HUFFMAN_H */
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user