1
mirror of https://github.com/mpv-player/mpv synced 2024-10-06 14:54:02 +02:00

AVC support moved to libavcodec, avcC atom is now passed in extradata

git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@13334 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
rtognimp 2004-09-13 21:21:48 +00:00
parent 26fc7d22bd
commit 49bc246607
2 changed files with 15 additions and 101 deletions

View File

@ -72,11 +72,6 @@ typedef struct {
double inv_qp_sum;
int ip_count;
int b_count;
// AVC data
int got_avcC;
int nal_length_size;
void *data_bak;
int len_bak;
} vd_ffmpeg_ctx;
//#ifdef FF_POSTPROCESS
@ -322,7 +317,8 @@ static int init(sh_video_t *sh){
sh->format == mmioFOURCC('Z','L','I','B') ||
sh->format == mmioFOURCC('M','P','4','V') ||
sh->format == mmioFOURCC('F','L','I','C') ||
sh->format == mmioFOURCC('S','N','O','W')
sh->format == mmioFOURCC('S','N','O','W') ||
sh->format == mmioFOURCC('a','v','c','1')
))
{
avctx->extradata_size = sh->bih->biSize-sizeof(BITMAPINFOHEADER);
@ -351,10 +347,6 @@ static int init(sh_video_t *sh){
memcpy(avctx->extradata, ((int*)sh->ImageDesc)+1, avctx->extradata_size);
}
if(sh->format == mmioFOURCC('a', 'v', 'c', '1')) {
ctx->got_avcC = 0;
}
if(sh->bih)
avctx->bits_per_sample= sh->bih->biBitCount;
@ -695,35 +687,6 @@ typedef struct dp_hdr_s {
} dp_hdr_t;
/**
* Add sync to a nal and queue it in buffer, increasing buffer size as needed
* @param dest pointer to current buffer area
* @param destsize pointer to size of current dest area
* @param source pointer to source nal data (after length bytes)
* @param nal_len length of nal data
*/
unsigned char* avc1_addnal(unsigned char *dest, int *destsize, unsigned char* source, int nal_len)
{
unsigned char *temp;
int tempsize;
tempsize = *destsize + nal_len + 4;
temp = malloc (tempsize);
if (dest)
memcpy (temp, dest, *destsize);
temp[*destsize] = 0;
temp[*destsize+1] = 0;
temp[*destsize+2] = 0;
temp[*destsize+3] = 1;
memcpy (temp + *destsize + 4, source, nal_len);
if (dest)
free(dest);
*destsize = tempsize;
return temp;
}
// decode a frame
static mp_image_t* decode(sh_video_t *sh,void* data,int len,int flags){
int got_picture=0;
@ -783,68 +746,9 @@ static mp_image_t* decode(sh_video_t *sh,void* data,int len,int flags){
data+= sizeof(dp_hdr_t);
}
/*
* Convert avc1 nals to annexb nals (remove lenght, add sync)
* If first frame extract and process avcC (configuration data)
*/
if(sh->format == mmioFOURCC('a', 'v', 'c', '1')) {
int bufsize = 0;
int nalsize;
unsigned char *p = data;
int i;
int cnt, poffs;
// Remember original values
ctx->data_bak = data;
ctx->len_bak = len;
if (!ctx->got_avcC) {
// Parse some parts of avcC, just for fun :)
mp_msg(MSGT_DECVIDEO, MSGL_V, "[ffmpeg] avcC version: %d\n", *(p));
mp_msg(MSGT_DECVIDEO, MSGL_V, "[ffmpeg] avcC profile: %d\n", *(p+1));
mp_msg(MSGT_DECVIDEO, MSGL_V, "[ffmpeg] avcC profile compatibility: %d\n", *(p+2));
mp_msg(MSGT_DECVIDEO, MSGL_V, "[ffmpeg] avcC level: %d\n", *(p+3));
mp_msg(MSGT_DECVIDEO, MSGL_V, "[ffmpeg] avcC nal length size: %d\n", ctx->nal_length_size = ((*(p+4))&0x03)+1);
mp_msg(MSGT_DECVIDEO, MSGL_V, "[ffmpeg] avcC number of sequence param sets: %d\n", cnt = (*(p+5) & 0x1f));
poffs = 6;
for (i = 0; i < cnt; i++) {
mp_msg(MSGT_DECVIDEO, MSGL_V, "[ffmpeg] avcC sps %d have length %d\n", i, nalsize = BE_16(p+poffs));
buf = avc1_addnal(buf, &bufsize, p + poffs + 2, nalsize);
poffs += nalsize + 2;
}
mp_msg(MSGT_DECVIDEO, MSGL_V, "[ffmpeg] avcC number of picture param sets: %d\n", *(p+poffs));
poffs++;
for (i = 0; i < cnt; i++) {
mp_msg(MSGT_DECVIDEO, MSGL_V, "[ffmpeg] avcC pps %d have length %d\n", i, nalsize = BE_16(p+poffs));
buf = avc1_addnal(buf, &bufsize, p + poffs + 2, nalsize);
poffs += nalsize + 2;
}
p += poffs;
ctx->got_avcC = 1;
}
while (p < (data + len)) {
nalsize = 0;
for(i = 0; i < ctx->nal_length_size; i++)
nalsize = (nalsize << 8) | (*p++);
mp_msg(MSGT_DECVIDEO, MSGL_DBG2, "[ffmpeg] avc1: nalsize = %d\n", nalsize);
buf = avc1_addnal(buf, &bufsize, p, nalsize);
p += nalsize;
len -= nalsize;
}
data = buf;
len = bufsize;
}
ret = avcodec_decode_video(avctx, pic,
&got_picture, data, len);
if(sh->format == mmioFOURCC('a', 'v', 'c', '1')) {
free(buf);
data = ctx->data_bak;
len = ctx->len_bak;
}
dr1= ctx->do_dr1;
if(ret<0) mp_msg(MSGT_DECVIDEO,MSGL_WARN, "Error while decoding frame!\n");
//printf("repeat: %d\n", pic->repeat_pict);

View File

@ -1117,14 +1117,14 @@ static void lschunks(demuxer_t* demuxer,int level,off_t endpos,mov_track_t* trak
if(atom_len > 8) {
int i, poffs, cnt;
// Parse some parts of avcC, just for fun :)
// avcC formatting happens in vd_ffmpeg, sps and pps are decoded in lavc
// real parsing is done by avc1 decoder
mp_msg(MSGT_DEMUX, MSGL_V, "MOV: avcC version: %d\n", *(trak->stdata+pos+8));
if (*(trak->stdata+pos+8) != 1)
mp_msg(MSGT_DEMUX, MSGL_ERR, "MOV: unknown avcC version (%d). Expexct problems.\n", *(trak->stdata+pos+9));
mp_msg(MSGT_DEMUX, MSGL_V, "MOV: avcC profile: %d\n", *(trak->stdata+pos+9));
mp_msg(MSGT_DEMUX, MSGL_V, "MOV: avcC profile compatibility: %d\n", *(trak->stdata+pos+10));
mp_msg(MSGT_DEMUX, MSGL_V, "MOV: avcC level: %d\n", *(trak->stdata+pos+11));
mp_msg(MSGT_DEMUX, MSGL_V, "MOV: avcC nal length size: %d\n", (*(trak->stdata+pos+12))&0x03+1);
mp_msg(MSGT_DEMUX, MSGL_V, "MOV: avcC nal length size: %d\n", ((*(trak->stdata+pos+12))&0x03)+1);
mp_msg(MSGT_DEMUX, MSGL_V, "MOV: avcC number of sequence param sets: %d\n", cnt = (*(trak->stdata+pos+13) & 0x1f));
poffs = pos + 14;
for (i = 0; i < cnt; i++) {
@ -1138,7 +1138,7 @@ static void lschunks(demuxer_t* demuxer,int level,off_t endpos,mov_track_t* trak
poffs += BE_16(trak->stdata+poffs) + 2;
}
// Copy avcC for the AVC decoder
// This data will be sent to decoder with first frame, before frame data
// This data will be put in extradata below, where BITMAPINFOHEADER is created
trak->stream_header_len = atom_len-8;
trak->stream_header = (unsigned char *)malloc(trak->stream_header_len);
memcpy(trak->stream_header, trak->stdata+pos+8, trak->stream_header_len);
@ -1269,9 +1269,19 @@ static void lschunks(demuxer_t* demuxer,int level,off_t endpos,mov_track_t* trak
}
else
{
if (trak->fourcc == mmioFOURCC('a','v','c','1')) {
sh->bih=malloc(sizeof(BITMAPINFOHEADER) + trak->stream_header_len);
memset(sh->bih,0,sizeof(BITMAPINFOHEADER) + trak->stream_header_len);
sh->bih->biSize=40 + trak->stream_header_len;
memcpy(((unsigned char *)sh->bih)+40, trak->stream_header, trak->stream_header_len);
free (trak->stream_header);
trak->stream_header_len = 0;
trak->stream_header = NULL;
} else {
sh->bih=malloc(sizeof(BITMAPINFOHEADER));
memset(sh->bih,0,sizeof(BITMAPINFOHEADER));
sh->bih->biSize=40;
}
}
sh->bih->biWidth=sh->disp_w;
sh->bih->biHeight=sh->disp_h;