2012-05-30 12 views
6

Obtengo esto del ejemplo de codificación en ffmpeg. Puedo seguir un poco el ejemplo autores de codificación de audio, pero me encuentro aturdido mirando el código C (os comentaba en números de bloque me refiero a ayudar a lo que estoy hablando) ...Comprensión de la codificación de video FFMPEG

static void video_encode_example(const char *filename) 
{ 
AVCodec *codec; 
AVCodecContext *c= NULL; 
int i, out_size, size, x, y, outbuf_size; 
FILE *f; 
AVFrame *picture; 
uint8_t *outbuf, *picture_buf;    //BLOCK ONE 
printf("Video encoding\n"); 

/* find the mpeg1 video encoder */ 
codec = avcodec_find_encoder(CODEC_ID_MPEG1VIDEO); 
if (!codec) { 
    fprintf(stderr, "codec not found\n"); 
    exit(1);        //BLOCK TWO 
} 

c= avcodec_alloc_context(); 
picture= avcodec_alloc_frame(); 
/* put sample parameters */ 
c->bit_rate = 400000; 
/* resolution must be a multiple of two */ 
c->width = 352; 
c->height = 288; 
/* frames per second */ 
c->time_base= (AVRational){1,25}; 
c->gop_size = 10; /* emit one intra frame every ten frames */ 
c->max_b_frames=1; 
c->pix_fmt = PIX_FMT_YUV420P;     //BLOCK THREE 

/* open it */ 
if (avcodec_open(c, codec) < 0) { 
    fprintf(stderr, "could not open codec\n"); 
    exit(1); 
} 
f = fopen(filename, "wb"); 
if (!f) { 
    fprintf(stderr, "could not open %s\n", filename); 
    exit(1); 
}            //BLOCK FOUR 

/* alloc image and output buffer */ 
outbuf_size = 100000; 
outbuf = malloc(outbuf_size); 
size = c->width * c->height; 
picture_buf = malloc((size * 3)/2); /* size for YUV 420 */ 
picture->data[0] = picture_buf; 
picture->data[1] = picture->data[0] + size; 
picture->data[2] = picture->data[1] + size/4; 
picture->linesize[0] = c->width; 
picture->linesize[1] = c->width/2; 
picture->linesize[2] = c->width/2;    //BLOCK FIVE 

/* encode 1 second of video */ 
for(i=0;i<25;i++) { 
    fflush(stdout); 
    /* prepare a dummy image */ 
    /* Y */ 
    for(y=0;y<c->height;y++) { 
     for(x=0;x<c->width;x++) { 
      picture->data[0][y * picture->linesize[0] + x] = x + y + i * 3; 
     } 
    }           //BLOCK SIX 

    /* Cb and Cr */ 
    for(y=0;y<c->height/2;y++) { 
     for(x=0;x<c->width/2;x++) { 
      picture->data[1][y * picture->linesize[1] + x] = 128 + y + i * 2; 
      picture->data[2][y * picture->linesize[2] + x] = 64 + x + i * 5; 
     } 
    }           //BLOCK SEVEN 

    /* encode the image */ 
    out_size = avcodec_encode_video(c, outbuf, outbuf_size, picture); 
    printf("encoding frame %3d (size=%5d)\n", i, out_size); 
    fwrite(outbuf, 1, out_size, f); 
}            //BLOCK EIGHT 

/* get the delayed frames */ 
for(; out_size; i++) { 
    fflush(stdout); 
    out_size = avcodec_encode_video(c, outbuf, outbuf_size, NULL); 
    printf("write frame %3d (size=%5d)\n", i, out_size); 
    fwrite(outbuf, 1, out_size, f); 
}            //BLOCK NINE 

/* add sequence end code to have a real mpeg file */ 
outbuf[0] = 0x00; 
outbuf[1] = 0x00; 
outbuf[2] = 0x01; 
outbuf[3] = 0xb7; 
fwrite(outbuf, 1, 4, f); 
fclose(f); 
free(picture_buf); 
free(outbuf); 
avcodec_close(c); 
av_free(c); 
av_free(picture); 
}           //BLOCK TEN 

Esto es lo Puedo obtener de los autores código bloque por bloque ...

BLOQUE UNO: inicialización de variables y punteros. No pude encontrar la estructura AVFrame todavía en el código fuente de ffmpeg, así que no sé a qué referencia hace referencia

BLOQUE DOS: utiliza un códec del archivo, si no se encuentra cerca.

BLOCK THREE: establece parámetros de muestra de video. Lo único que realmente no entiendo es tamaño de gop. Leí acerca de intra frames y aún no entiendo qué son.

bloque de cuatro: Abrir el archivo para escritura ...

pabellón cinco: Aquí es donde realmente empiezan a perder mí. Probablemente sea porque no sé exactamente qué es AVFrame, pero ¿por qué solo usan 3/2 del tamaño de la imagen?

BLOCK SIX & SIETE: No entiendo qué están tratando de lograr con esta matemática.

BLOQUE DE OCHO: Parece que la función avcodec hace todo el trabajo aquí, no se ocupe de esa, por el momento ..

BLOQUE NUEVE: Ya que es fuera del bastidor 25 para el lazo Asumo que llegue el sobrante marcos?

Bloque Diez: Cerrar, la memoria libre, etc ...

Sé que esto es un gran bloque de código debe ser confundido con, cualquier entrada sería de gran ayuda. Me metieron por la cabeza en el trabajo. Gracias de antemano SO.

+0

Pasé una gran cantidad de tiempo esta mañana mirando los bloques seis y siete cuando las matemáticas se hacen en la matriz multidimensional, y tengo que decir que estoy tan atrapado como ayer cuando salía del trabajo :( – SetSlapShot

+0

¿Qué tiene de misterioso el bloque seis y el siete? El comentario '/ * prepara una imagen ficticia */'debe darle toda la información que necesita. Todo lo que se hace es generar algunos datos de píxeles que terminarán como un gradiente que cambia con el índice de marco. – HonkyTonk

+0

Votación para cerrar como demasiado amplia. Por favor, concéntrese en un punto por pregunta. –

Respuesta

3

Como HonkyTonk ya respondió, los comentarios lo deletrean: prepare una imagen ficticia. Supongo que podría estar confundido acerca de exactamente cómo se está generando la imagen ficticia, especialmente si no está familiarizado con el espacio de color YUV/YCbCr. Read the Wikipedia treatment for the basics.

Muchos códecs de video funcionan en el espacio de color YUV. Esto a menudo es confuso para los programadores que solo están acostumbrados a tratar en RGB. El resumen ejecutivo es que, para esta variación (YUV 4: 2: 0 planar), cada píxel de la imagen obtiene una muestra Y (tenga en cuenta que el ciclo Y itera sobre cada par (x, y)), mientras que 2x2 píxel cuadrán. comparta una muestra U/Cb y una muestra V/Cr (observe en el bloque siete que la iteración es sobre ancho/2 y alto/2).

Parece que el patrón generado es algún tipo de gradiente. Si desea producir un cambio conocido, configure Y/Cb/Cr en 0 y la imagen ficticia será toda verde. Establezca Cb y Cr en 128 y establezca Y en 255 y obtenga un marco blanco; deslice Y a 0 para ver negro; establezca Y en cualquier valor intermedio mientras mantiene Cb y Cr en 128 para ver tonos de gris.

4

comparto mi comprensión [¡Silencie una respuesta tardía!]

YUV420p:

YUV 420P o YCbCr, es alternativa a RGB repersetation, y contiene 3

planos, a saber, Y (componente luma) U (Y-Cb) & V (Y-Cr) componentes. [ans Y-Cb-Cr-Cg =

Constante, no necesitamos almacenar el componente Cg, como generalmente se puede calcular.] Al igual que RGB888, que requiere 3 bytes por píxel, YUV420 requiere 1.5 bytes un píxel [@find (Cómo

los 12 bits se utilizan para lo comppnent en lo ratio)] Aquí P -stands para progresiva, que significa que los marcos son progresivas, lo que significa V sigue U, U sigue y y YUV Frame es una matriz de bytes, ¡simplemente! Otro es I-resiste intercalaciones, significa que los datos planar UV son intercalaciones entre los datos del plano Y de manera específica [@Find (De qué manera)]

Cuestiones relacionadas