Commit e4cb187d authored by Michael Niedermayer's avatar Michael Niedermayer

remove duplicated find_frame_end() code

move codec specific code from parser.c -> <codecname>.c as far as its easily possible

Originally committed as revision 3087 to svn://svn.ffmpeg.org/ffmpeg/trunk
parent 20da3179
......@@ -306,8 +306,7 @@ static int decode_slice(MpegEncContext *s){
* 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 ff_mpeg4_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size){
int vop_found, i;
uint32_t state;
......@@ -326,23 +325,25 @@ static int mpeg4_find_frame_end(MpegEncContext *s, uint8_t *buf, int buf_size){
}
}
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;
if(vop_found){
/* EOF considered as end of frame */
if (buf_size == 0)
return 0;
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;
static int h263_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size){
int vop_found, i;
uint32_t state;
......@@ -377,6 +378,27 @@ static int h263_find_frame_end(MpegEncContext *s, uint8_t *buf, int buf_size){
return END_NOT_FOUND;
}
static int h263_parse(AVCodecParserContext *s,
AVCodecContext *avctx,
uint8_t **poutbuf, int *poutbuf_size,
const uint8_t *buf, int buf_size)
{
ParseContext *pc = s->priv_data;
int next;
next= h263_find_frame_end(pc, buf, buf_size);
if (ff_combine_frame(pc, next, (uint8_t **)&buf, &buf_size) < 0) {
*poutbuf = NULL;
*poutbuf_size = 0;
return buf_size;
}
*poutbuf = (uint8_t *)buf;
*poutbuf_size = buf_size;
return next;
}
int ff_h263_decode_frame(AVCodecContext *avctx,
void *data, int *data_size,
uint8_t *buf, int buf_size)
......@@ -414,15 +436,15 @@ uint64_t time= rdtsc();
int next;
if(s->codec_id==CODEC_ID_MPEG4){
next= mpeg4_find_frame_end(s, buf, buf_size);
next= ff_mpeg4_find_frame_end(&s->parse_context, buf, buf_size);
}else if(s->codec_id==CODEC_ID_H263){
next= h263_find_frame_end(s, buf, buf_size);
next= 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");
return -1;
}
if( ff_combine_frame(s, next, &buf, &buf_size) < 0 )
if( ff_combine_frame(&s->parse_context, next, &buf, &buf_size) < 0 )
return buf_size;
}
......@@ -843,3 +865,11 @@ AVCodec flv_decoder = {
ff_h263_decode_frame,
CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1
};
AVCodecParser h263_parser = {
{ CODEC_ID_H263 },
sizeof(ParseContext),
NULL,
h263_parse,
ff_parse_close,
};
......@@ -5520,8 +5520,7 @@ static inline int decode_picture_parameter_set(H264Context *h){
* 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 find_frame_end(MpegEncContext *s, uint8_t *buf, int buf_size){
ParseContext *pc= &s->parse_context;
static int find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size){
int i;
uint32_t state;
//printf("first %02X%02X%02X%02X\n", buf[0], buf[1],buf[2],buf[3]);
......@@ -5544,6 +5543,27 @@ static int find_frame_end(MpegEncContext *s, uint8_t *buf, int buf_size){
return END_NOT_FOUND;
}
static int h264_parse(AVCodecParserContext *s,
AVCodecContext *avctx,
uint8_t **poutbuf, int *poutbuf_size,
const uint8_t *buf, int buf_size)
{
ParseContext *pc = s->priv_data;
int next;
next= find_frame_end(pc, buf, buf_size);
if (ff_combine_frame(pc, next, (uint8_t **)&buf, &buf_size) < 0) {
*poutbuf = NULL;
*poutbuf_size = 0;
return buf_size;
}
*poutbuf = (uint8_t *)buf;
*poutbuf_size = buf_size;
return next;
}
static int decode_nal_units(H264Context *h, uint8_t *buf, int buf_size){
MpegEncContext * const s = &h->s;
AVCodecContext * const avctx= s->avctx;
......@@ -5701,9 +5721,9 @@ static int decode_frame(AVCodecContext *avctx,
}
if(s->flags&CODEC_FLAG_TRUNCATED){
int next= find_frame_end(s, buf, buf_size);
int next= find_frame_end(&s->parse_context, buf, buf_size);
if( ff_combine_frame(s, next, &buf, &buf_size) < 0 )
if( ff_combine_frame(&s->parse_context, next, &buf, &buf_size) < 0 )
return buf_size;
//printf("next:%d buf_size:%d last_index:%d\n", next, buf_size, s->parse_context.last_index);
}
......@@ -5970,4 +5990,12 @@ AVCodec h264_decoder = {
/*CODEC_CAP_DRAW_HORIZ_BAND |*/ CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED,
};
AVCodecParser h264_parser = {
{ CODEC_ID_H264 },
sizeof(ParseContext),
NULL,
h264_parse,
ff_parse_close,
};
#include "svq3.c"
......@@ -2715,8 +2715,8 @@ static void mpeg_decode_gop(AVCodecContext *avctx,
* 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 mpeg1_find_frame_end(MpegEncContext *s, uint8_t *buf, int buf_size){
ParseContext *pc= &s->parse_context;
int ff_mpeg1_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size)
{
int i;
uint32_t state;
......@@ -2735,6 +2735,9 @@ static int mpeg1_find_frame_end(MpegEncContext *s, uint8_t *buf, int buf_size){
}
if(pc->frame_start_found){
/* EOF considered as end of frame */
if (buf_size == 0)
return 0;
for(; i<buf_size; i++){
state= (state<<8) | buf[i];
if((state&0xFFFFFF00) == 0x100){
......@@ -2775,9 +2778,9 @@ static int mpeg_decode_frame(AVCodecContext *avctx,
}
if(s2->flags&CODEC_FLAG_TRUNCATED){
int next= mpeg1_find_frame_end(s2, buf, buf_size);
int next= ff_mpeg1_find_frame_end(&s2->parse_context, buf, buf_size);
if( ff_combine_frame(s2, next, &buf, &buf_size) < 0 )
if( ff_combine_frame(&s2->parse_context, next, &buf, &buf_size) < 0 )
return buf_size;
}
......
......@@ -3698,64 +3698,6 @@ static void encode_mb(MpegEncContext *s, int motion_x, int motion_y)
#endif //CONFIG_ENCODERS
/**
* combines the (truncated) bitstream to a complete frame
* @returns -1 if no complete frame could be created
*/
int ff_combine_frame( MpegEncContext *s, int next, uint8_t **buf, int *buf_size){
ParseContext *pc= &s->parse_context;
#if 0
if(pc->overread){
printf("overread %d, state:%X next:%d index:%d o_index:%d\n", pc->overread, pc->state, next, pc->index, pc->overread_index);
printf("%X %X %X %X\n", (*buf)[0], (*buf)[1],(*buf)[2],(*buf)[3]);
}
#endif
/* copy overreaded byes from last frame into buffer */
for(; pc->overread>0; pc->overread--){
pc->buffer[pc->index++]= pc->buffer[pc->overread_index++];
}
pc->last_index= pc->index;
/* copy into buffer end return */
if(next == END_NOT_FOUND){
pc->buffer= av_fast_realloc(pc->buffer, &pc->buffer_size, (*buf_size) + pc->index + FF_INPUT_BUFFER_PADDING_SIZE);
memcpy(&pc->buffer[pc->index], *buf, *buf_size);
pc->index += *buf_size;
return -1;
}
*buf_size=
pc->overread_index= pc->index + next;
/* append to buffer */
if(pc->index){
pc->buffer= av_fast_realloc(pc->buffer, &pc->buffer_size, next + pc->index + FF_INPUT_BUFFER_PADDING_SIZE);
memcpy(&pc->buffer[pc->index], *buf, next + FF_INPUT_BUFFER_PADDING_SIZE );
pc->index = 0;
*buf= pc->buffer;
}
/* store overread bytes */
for(;next < 0; next++){
pc->state = (pc->state<<8) | pc->buffer[pc->last_index + next];
pc->overread++;
}
#if 0
if(pc->overread){
printf("overread %d, state:%X next:%d index:%d o_index:%d\n", pc->overread, pc->state, next, pc->index, pc->overread_index);
printf("%X %X %X %X\n", (*buf)[0], (*buf)[1],(*buf)[2],(*buf)[3]);
}
#endif
return 0;
}
void ff_mpeg_flush(AVCodecContext *avctx){
int i;
MpegEncContext *s = avctx->priv_data;
......
......@@ -749,7 +749,8 @@ void ff_draw_horiz_band(MpegEncContext *s, int y, int h);
void ff_emulated_edge_mc(uint8_t *buf, uint8_t *src, int linesize, int block_w, int block_h,
int src_x, int src_y, int w, int h);
#define END_NOT_FOUND -100
int ff_combine_frame( MpegEncContext *s, int next, uint8_t **buf, int *buf_size);
int ff_combine_frame(ParseContext *pc, int next, uint8_t **buf, int *buf_size);
void ff_parse_close(AVCodecParserContext *s);
void ff_mpeg_flush(AVCodecContext *avctx);
void ff_print_debug_info(MpegEncContext *s, AVFrame *pict);
void ff_write_quant_matrix(PutBitContext *pb, int16_t *matrix);
......
......@@ -144,15 +144,8 @@ void av_parser_close(AVCodecParserContext *s)
#define SLICE_MAX_START_CODE 0x000001af
typedef struct ParseContext1{
uint8_t *buffer;
int index;
int last_index;
int buffer_size;
uint32_t state; ///< contains the last few bytes in MSB order
int frame_start_found;
int overread; ///< the number of bytes which where irreversibly read from the next frame
int overread_index; ///< the index into ParseContext1.buffer of the overreaded bytes
ParseContext pc;
/* XXX/FIXME PC1 vs. PC */
/* MPEG2 specific */
int frame_rate;
int progressive_sequence;
......@@ -167,7 +160,7 @@ typedef struct ParseContext1{
* combines the (truncated) bitstream to a complete frame
* @returns -1 if no complete frame could be created
*/
static int ff_combine_frame1(ParseContext1 *pc, int next, uint8_t **buf, int *buf_size)
int ff_combine_frame(ParseContext *pc, int next, uint8_t **buf, int *buf_size)
{
#if 0
if(pc->overread){
......@@ -220,48 +213,6 @@ static int ff_combine_frame1(ParseContext1 *pc, int next, uint8_t **buf, int *bu
return 0;
}
/**
* 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 mpeg1_find_frame_end(ParseContext1 *pc, const uint8_t *buf, int buf_size)
{
int i;
uint32_t state;
state= pc->state;
i=0;
if(!pc->frame_start_found){
for(i=0; i<buf_size; i++){
state= (state<<8) | buf[i];
if(state >= SLICE_MIN_START_CODE && state <= SLICE_MAX_START_CODE){
i++;
pc->frame_start_found=1;
break;
}
}
}
if(pc->frame_start_found){
/* EOF considered as end of frame */
if (buf_size == 0)
return 0;
for(; i<buf_size; i++){
state= (state<<8) | buf[i];
if((state&0xFFFFFF00) == 0x100){
if(state < SLICE_MIN_START_CODE || state > SLICE_MAX_START_CODE){
pc->frame_start_found=0;
pc->state=-1;
return i-3;
}
}
}
}
pc->state= state;
return END_NOT_FOUND;
}
static int find_start_code(const uint8_t **pbuf_ptr, const uint8_t *buf_end)
{
const uint8_t *buf_ptr;
......@@ -404,12 +355,13 @@ static int mpegvideo_parse(AVCodecParserContext *s,
uint8_t **poutbuf, int *poutbuf_size,
const uint8_t *buf, int buf_size)
{
ParseContext1 *pc = s->priv_data;
ParseContext1 *pc1 = s->priv_data;
ParseContext *pc= &pc1->pc;
int next;
next= mpeg1_find_frame_end(pc, buf, buf_size);
next= ff_mpeg1_find_frame_end(pc, buf, buf_size);
if (ff_combine_frame1(pc, next, (uint8_t **)&buf, &buf_size) < 0) {
if (ff_combine_frame(pc, next, (uint8_t **)&buf, &buf_size) < 0) {
*poutbuf = NULL;
*poutbuf_size = 0;
return buf_size;
......@@ -428,59 +380,23 @@ static int mpegvideo_parse(AVCodecParserContext *s,
return next;
}
static void mpegvideo_parse_close(AVCodecParserContext *s)
void ff_parse_close(AVCodecParserContext *s)
{
ParseContext1 *pc = s->priv_data;
ParseContext *pc = s->priv_data;
av_free(pc->buffer);
av_free(pc->enc);
}
/*************************/
/**
* 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(ParseContext1 *pc,
const uint8_t *buf, int buf_size)
static void parse1_close(AVCodecParserContext *s)
{
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;
}
}
}
ParseContext1 *pc1 = s->priv_data;
if(vop_found){
/* EOF considered as end of frame */
if (buf_size == 0)
return 0;
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;
av_free(pc1->pc.buffer);
av_free(pc1->enc);
}
/*************************/
/* used by parser */
/* XXX: make it use less memory */
static int av_mpeg4_decode_header(AVCodecParserContext *s1,
......@@ -526,12 +442,12 @@ static int mpeg4video_parse(AVCodecParserContext *s,
uint8_t **poutbuf, int *poutbuf_size,
const uint8_t *buf, int buf_size)
{
ParseContext1 *pc = s->priv_data;
ParseContext *pc = s->priv_data;
int next;
next= mpeg4_find_frame_end(pc, buf, buf_size);
next= ff_mpeg4_find_frame_end(pc, buf, buf_size);
if (ff_combine_frame1(pc, next, (uint8_t **)&buf, &buf_size) < 0) {
if (ff_combine_frame(pc, next, (uint8_t **)&buf, &buf_size) < 0) {
*poutbuf = NULL;
*poutbuf_size = 0;
return buf_size;
......@@ -545,116 +461,6 @@ static int mpeg4video_parse(AVCodecParserContext *s,
/*************************/
static int h263_find_frame_end(ParseContext1 *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,
uint8_t **poutbuf, int *poutbuf_size,
const uint8_t *buf, int buf_size)
{
ParseContext1 *pc = s->priv_data;
int next;
next= h263_find_frame_end(pc, buf, buf_size);
if (ff_combine_frame1(pc, next, (uint8_t **)&buf, &buf_size) < 0) {
*poutbuf = NULL;
*poutbuf_size = 0;
return buf_size;
}
*poutbuf = (uint8_t *)buf;
*poutbuf_size = buf_size;
return next;
}
/*************************/
/**
* 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 h264_find_frame_end(ParseContext1 *pc, const uint8_t *buf, int buf_size)
{
int i;
uint32_t state;
//printf("first %02X%02X%02X%02X\n", buf[0], buf[1],buf[2],buf[3]);
// mb_addr= pc->mb_addr - 1;
state= pc->state;
//FIXME this will fail with slices
for(i=0; i<buf_size; i++){
state= (state<<8) | buf[i];
if((state&0xFFFFFF1F) == 0x101 || (state&0xFFFFFF1F) == 0x102 || (state&0xFFFFFF1F) == 0x105){
if(pc->frame_start_found){
pc->state=-1;
pc->frame_start_found= 0;
return i-3;
}
pc->frame_start_found= 1;
}
}
pc->state= state;
return END_NOT_FOUND;
}
static int h264_parse(AVCodecParserContext *s,
AVCodecContext *avctx,
uint8_t **poutbuf, int *poutbuf_size,
const uint8_t *buf, int buf_size)
{
ParseContext1 *pc = s->priv_data;
int next;
next= h264_find_frame_end(pc, buf, buf_size);
if (ff_combine_frame1(pc, next, (uint8_t **)&buf, &buf_size) < 0) {
*poutbuf = NULL;
*poutbuf_size = 0;
return buf_size;
}
*poutbuf = (uint8_t *)buf;
*poutbuf_size = buf_size;
return next;
}
/*************************/
typedef struct MpegAudioParseContext {
uint8_t inbuf[MPA_MAX_CODED_FRAME_SIZE]; /* input buffer */
uint8_t *inbuf_ptr;
......@@ -913,7 +719,7 @@ AVCodecParser mpegvideo_parser = {
sizeof(ParseContext1),
NULL,
mpegvideo_parse,
mpegvideo_parse_close,
parse1_close,
};
AVCodecParser mpeg4video_parser = {
......@@ -921,23 +727,7 @@ AVCodecParser mpeg4video_parser = {
sizeof(ParseContext1),
mpeg4video_parse_init,
mpeg4video_parse,
mpegvideo_parse_close,
};
AVCodecParser h263_parser = {
{ CODEC_ID_H263 },
sizeof(ParseContext1),
NULL,
h263_parse,
mpegvideo_parse_close,
};
AVCodecParser h264_parser = {
{ CODEC_ID_H264 },
sizeof(ParseContext1),
NULL,
h264_parse,
mpegvideo_parse_close,
parse1_close,
};
AVCodecParser mpegaudio_parser = {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment