viernes, 21 de mayo de 2010

Detección de las cabeceras de los flujos de vídeo que son capaces de capturar imágenes fijas

uvc_device = uvc_streaming + ....
uvc_straming = uvc_straming_header + ...

uvc_straming_header = bStillCaptureMethod + ... 
Detalle de algunas estructuras de linux-uvc


He realizado un pequeño ejemplo de como podría detectarse las cabeceras de los flujos de vídeo que son capaces de capturar imágenes fijas. Este ejemplo es similar a la función uvc_stream_by_id.

Digo ejemplo, ya que no sé como pudiera abrir la estructura
uvc_device, que es necesaria para la detección de dichos flujos de vídeo que se encuentran en la estructura uvc_streaming.
De ellos se desprenden la estructura
uvc_streaming_header donde se encuentra el byte bStillCaptureMethod, que es la información que se necesita para filtrar las cabeceras.

Para usar las estructuras, he pensado que una
lista como las incluidas en Linux pudiera ser lo más intuitivo.


En cuanto pudiera leer el uvc_device, quisiera depurar el ejemplo para que así ya pueda pasar a leer las resoluciones de las imágenes fijas.





Ejemplo:

//  We will need uvcvideo.h                                                                           
#include "uvcvideo.h"                                                                                 




//  This function will print all information of a header
void print_streaming_header (uvc_streaming_header header)
{                                                        
  printf("######################\n");                    
  printf("bNumFormats:        %d\n", header.bNumFormats);
  printf("bEndpointAddress:   %d\n", header.bEndPointAddress);
  printf("bTerminalLink:      %d\n", header.bTerminalLink);   
  printf("bControlSize:       %d\n", header.bControlSize);    
  printf("bmaControls:        %d\n", header.bmaControls);     
  printf("bmInfo:             %d\n", header.bmInfo);          
  printf("bStillCaptureMethod:%d\n",header.bStillCaptureMethod);
  printf("bTriggerSupport:    %d\n", header.bTriggerSupport);   
  printf("bTriggerSupport:    %d\n", header.bTriggerSupport);   
  printf("bTriggerUsage:      %d\n", header.bTriggerUsage);     
  printf("~~~~~~~~~~~~~~~~~~~~~~\n");                           
  return;                                                       
}                                                               




//  This function will print all headers that are in a list
void print_streaming_all_streams_headers (                 
                                       list_head *list_streams);
{                                                               
  struct uvc_streaming_header *header;                          
  list_for_each_entry(header, list_streams->header, list) {
    print_streaming_header(&header);
  }
  return;
}




//  This function will return all streams that are usefull for
//  capturing still image
void uvc_still_bStillCaptureMethod (struct uvc_device *dev,
                               list_head *list_uvc_stream_still)
{
  struct uvc_streaming *stream;


  //  We need to init our list ( linux/list.h )
  LIST_HEAD_INIT(&list_uvc_stream_still);


  list_for_each_entry (stream, &dev->streams, list) {
    //  We need all stream that you
    if (stream->header.bStillCaptureMethod == 2)
      list_add_tail(list_uvc_stream_still, stream);
  }
}




int main (){
  struct uvc_device dev;
  struct list_head  list_uvc_stream_still;


  //  How can I open my webcam dev?
  //  open_dev(dev);


  uvc_still_bStillCaptureMethod(&dev, &list_uvc_stream_still);
  print_streaming_all_streams_headers (list_uvc_stream_still);
}

viernes, 14 de mayo de 2010

"Un contenedor que contiene otro contenedor"


Muchas veces existen en la vida, una cosa que contiene otras. El tipo ejemplo son las Matrioskas.

Eso también pasa en la informática, una cámara web puede tiene varios interfaces: el flujo de vídeo, el micrófono, el botón, ...

Otro ejemplo serían las listas, un tipo de estructura de datos que sirve para almacenar información. Como las de las bodas que tienen un conjunto de nombres con un orden asociado.

La operación más útil, en mi opinión, que puede hacer una lista es el recorrer cada uno de los miembros de la lista: list_for_each.
Digo esto, porque muchas veces nos interesará aplicar una función a cada uno de los miembros de la lista. Siguiendo con el ejemplo de la boda, podríamos decir "dame los de la familia de la novia" o "dame los niños pequeños para ponerlos juntos en una mesa" .

La utilización de las listas tiene que ver con la función uvc_stream_by_id, ya que se parece a una función que tendré que realizar para conseguir la información asociada a los interfaces.