| 41 | | struct dc1394_frame_format { |
| 42 | | int width; |
| 43 | | int height; |
| 44 | | enum PixelFormat pix_fmt; |
| 45 | | int frame_size_id; |
| 46 | | } dc1394_frame_formats[] = { |
| 47 | | { 320, 240, PIX_FMT_UYVY422, DC1394_VIDEO_MODE_320x240_YUV422 }, |
| 48 | | { 640, 480, PIX_FMT_UYYVYY411, DC1394_VIDEO_MODE_640x480_YUV411 }, |
| 49 | | { 640, 480, PIX_FMT_UYVY422, DC1394_VIDEO_MODE_640x480_YUV422 }, |
| 50 | | { 0, 0, 0, 0 } /* gotta be the last one */ |
| | 44 | /* The list of color codings that we support, sorted in descending preference. |
| | 45 | * We assume big endian for the dc1394 16bit modes: libdc1394 never sets the |
| | 46 | * flag little_endian in dc1394video_frame_t. */ |
| | 47 | struct dc1394_color_coding { |
| | 48 | int pix_fmt; |
| | 49 | uint32_t coding; |
| | 50 | } dc1394_color_codings[] = { |
| | 51 | { PIX_FMT_UYVY422, DC1394_COLOR_CODING_YUV422 }, |
| | 52 | { PIX_FMT_UYYVYY411, DC1394_COLOR_CODING_YUV411 }, |
| | 53 | { PIX_FMT_RGB24, DC1394_COLOR_CODING_RGB8 }, |
| | 54 | { PIX_FMT_GRAY8, DC1394_COLOR_CODING_MONO8 }, |
| | 55 | { PIX_FMT_RGB48BE, DC1394_COLOR_CODING_RGB16 }, |
| | 56 | { PIX_FMT_GRAY16BE, DC1394_COLOR_CODING_MONO16 }, |
| | 57 | { PIX_FMT_NONE, 0 } /* gotta be the last one */ |
| 71 | | dc1394_data* dc1394 = c->priv_data; |
| 72 | | AVStream* vst; |
| 73 | | struct dc1394_frame_format *fmt; |
| 74 | | struct dc1394_frame_rate *fps; |
| 75 | | enum PixelFormat pix_fmt = ap->pix_fmt == PIX_FMT_NONE ? PIX_FMT_UYVY422 : ap->pix_fmt; /* defaults */ |
| 76 | | int width = !ap->width ? 320 : ap->width; |
| 77 | | int height = !ap->height ? 240 : ap->height; |
| 78 | | int frame_rate = !ap->time_base.num ? 30000 : av_rescale(1000, ap->time_base.den, ap->time_base.num); |
| 79 | | |
| 80 | | for (fmt = dc1394_frame_formats; fmt->width; fmt++) |
| 81 | | if (fmt->pix_fmt == pix_fmt && fmt->width == width && fmt->height == height) |
| 82 | | break; |
| 83 | | |
| 84 | | for (fps = dc1394_frame_rates; fps->frame_rate; fps++) |
| 85 | | if (fps->frame_rate == frame_rate) |
| 86 | | break; |
| 87 | | |
| 88 | | if (!fps->frame_rate || !fmt->width) { |
| 89 | | av_log(c, AV_LOG_ERROR, "Can't find matching camera format for %s, %dx%d@%d:1000fps\n", avcodec_get_pix_fmt_name(pix_fmt), |
| 90 | | width, height, frame_rate); |
| 91 | | goto out; |
| | 78 | const dc1394video_mode_t *a = va; |
| | 79 | const dc1394video_mode_t *b = vb; |
| | 80 | const struct dc1394_color_coding *c; |
| | 81 | uint32_t a_w, a_h, a_c; |
| | 82 | uint32_t b_w, b_h, b_c; |
| | 83 | |
| | 84 | dc1394_get_image_size_from_video_mode (NULL, *a, &a_w, &a_h); |
| | 85 | dc1394_get_image_size_from_video_mode (NULL, *b, &b_w, &b_h); |
| | 86 | if (a_w == b_w && a_h == b_h) { |
| | 87 | dc1394_get_color_coding_from_video_mode (NULL, *a, &a_c); |
| | 88 | dc1394_get_color_coding_from_video_mode (NULL, *b, &b_c); |
| | 89 | for (c = dc1394_color_codings; c->pix_fmt != PIX_FMT_NONE; c++) { |
| | 90 | if (a_c == c->coding && b_c != c->coding) |
| | 91 | return -1; |
| | 92 | else if (b_c == c->coding && a_c != c->coding) |
| | 93 | return +1; |
| | 94 | } |
| | 95 | return 0; |
| | 96 | } else { |
| | 97 | return (a_w > b_w || (a_w == b_w && a_h > b_h)) ? -1 : +1; |
| | 134 | /* Get the list of video modes supported by the camera. */ |
| | 135 | res = dc1394_video_get_supported_modes (dc1394->camera, &video_modes); |
| | 136 | if (res != DC1394_SUCCESS) { |
| | 137 | av_log(c, AV_LOG_ERROR, "Could not get video formats.\n"); |
| | 138 | goto out_camera; |
| | 139 | } |
| | 140 | /* Remove formats that we currently do not support as they would require |
| | 141 | * much more work. For the remaining modes, the functions |
| | 142 | * dc1394_get_image_size_from_video_mode and |
| | 143 | * dc1394_get_color_coding_from_video_mode do not need to query the camera, |
| | 144 | * and thus cannot fail. */ |
| | 145 | for (i = 0; i < video_modes.num;) { |
| | 146 | if (video_modes.modes[i] == DC1394_VIDEO_MODE_EXIF |
| | 147 | || (video_modes.modes[i] >= DC1394_VIDEO_MODE_FORMAT7_MIN |
| | 148 | && video_modes.modes[i] <= DC1394_VIDEO_MODE_FORMAT7_MAX)) { |
| | 149 | memmove(video_modes.modes + i, video_modes.modes + i + 1, |
| | 150 | (video_modes.num - i - 1) * sizeof(video_modes.modes[0])); |
| | 151 | video_modes.num--; |
| | 152 | } else { |
| | 153 | i++; |
| | 154 | } |
| | 155 | } |
| | 156 | /* Remove formats with color codings that we cannot handle. */ |
| | 157 | for (i = 0; i < video_modes.num;) { |
| | 158 | dc1394_get_color_coding_from_video_mode (NULL, |
| | 159 | video_modes.modes[i], &color_coding); |
| | 160 | for (cc = dc1394_color_codings; cc->pix_fmt != PIX_FMT_NONE; cc++) |
| | 161 | if (cc->coding == color_coding) |
| | 162 | break; |
| | 163 | if (cc->pix_fmt == PIX_FMT_NONE) { |
| | 164 | memmove(video_modes.modes + i, video_modes.modes + i + 1, |
| | 165 | (video_modes.num - i - 1) * sizeof(video_modes.modes[0])); |
| | 166 | video_modes.num--; |
| | 167 | } else { |
| | 168 | i++; |
| | 169 | } |
| | 170 | } |
| | 171 | if (video_modes.num == 0) { |
| | 172 | av_log(c, AV_LOG_ERROR, "No supported video modes available.\n"); |
| | 173 | goto out_camera; |
| | 174 | } |
| | 175 | /* Sort the video modes according to preference. */ |
| | 176 | qsort(video_modes.modes, video_modes.num, sizeof(video_modes.modes[0]), |
| | 177 | dc1394_video_mode_cmp); |
| | 178 | |
| | 179 | /* Frame size: if not specified, use the largest that is available */ |
| | 180 | if (ap->width && ap->height) { |
| | 181 | req_width = ap->width; |
| | 182 | req_height = ap->height; |
| | 183 | } else { |
| | 184 | dc1394_get_image_size_from_video_mode (NULL, |
| | 185 | video_modes.modes[0], &req_width, &req_height); |
| | 186 | } |
| | 187 | /* Pixel format: as a fallback, use pixel format of the preferred mode */ |
| | 188 | if (ap->pix_fmt == PIX_FMT_NONE) { |
| | 189 | dc1394_get_color_coding_from_video_mode (NULL, |
| | 190 | video_modes.modes[0], &req_color_coding); |
| | 191 | } else { |
| | 192 | for (cc = dc1394_color_codings; cc->pix_fmt != PIX_FMT_NONE; cc++) { |
| | 193 | if (cc->pix_fmt == ap->pix_fmt) { |
| | 194 | req_color_coding = cc->coding; |
| | 195 | break; |
| | 196 | } |
| | 197 | } |
| | 198 | if (cc->pix_fmt == PIX_FMT_NONE) { |
| | 199 | av_log(c, AV_LOG_WARNING, |
| | 200 | "Requested pixel format is not supported, using fallback.\n"); |
| | 201 | dc1394_get_color_coding_from_video_mode (NULL, |
| | 202 | video_modes.modes[0], &req_color_coding); |
| | 203 | } |
| | 204 | } |
| | 205 | |
| | 206 | /* Now look for a matching video mode. */ |
| | 207 | for (i = 0; i < video_modes.num; i++) { |
| | 208 | dc1394_get_image_size_from_video_mode (NULL, |
| | 209 | video_modes.modes[i], &width, &height); |
| | 210 | dc1394_get_color_coding_from_video_mode (NULL, |
| | 211 | video_modes.modes[i], &color_coding); |
| | 212 | if (width == req_width && height == req_height |
| | 213 | && color_coding == req_color_coding) { |
| | 214 | break; |
| | 215 | } |
| | 216 | } |
| | 217 | /* Fall back to the preferred mode. */ |
| | 218 | if (i == video_modes.num) { |
| | 219 | i = 0; |
| | 220 | av_log(c, AV_LOG_WARNING, |
| | 221 | "Requested frame size / pixel format is not available, using fallback.\n"); |
| | 222 | } |
| | 223 | video_mode = video_modes.modes[i]; |
| | 224 | /* Get the final size and pixel format. */ |
| | 225 | dc1394_get_image_size_from_video_mode (NULL, video_mode, &width, &height); |
| | 226 | final_width = width; |
| | 227 | final_height = height; |
| | 228 | dc1394_get_color_coding_from_video_mode (NULL, video_mode, &color_coding); |
| | 229 | for (cc = dc1394_color_codings; cc->pix_fmt != PIX_FMT_NONE; cc++) { |
| | 230 | if (cc->coding == color_coding) { |
| | 231 | final_pix_fmt = cc->pix_fmt; |
| | 232 | break; |
| | 233 | } |
| | 234 | } |
| | 235 | |
| | 236 | /* Get the list of frame rates supported by the camera for the selected |
| | 237 | * video mode. This list is sorted in ascending order according to libdc1394 |
| | 238 | * example programs. */ |
| | 239 | res = dc1394_video_get_supported_framerates (dc1394->camera, video_mode, |
| | 240 | &frame_rates); |
| | 241 | if (res != DC1394_SUCCESS || frame_rates.num == 0) { |
| | 242 | av_log(c, AV_LOG_ERROR, "Cannot get frame rates for video mode.\n"); |
| | 243 | goto out_camera; |
| | 244 | } |
| | 245 | if (!ap->time_base.num) { |
| | 246 | /* If not specified, use the highest rate available. */ |
| | 247 | frame_rate = frame_rates.framerates[frame_rates.num - 1]; |
| | 248 | } else { |
| | 249 | /* See if the requested frame rate is supported. */ |
| | 250 | req_frame_rate = av_rescale(1000, ap->time_base.den, ap->time_base.num); |
| | 251 | for (fr = dc1394_frame_rates; fr->frame_rate; fr++) { |
| | 252 | if (fr->frame_rate == req_frame_rate) { |
| | 253 | frame_rate = fr->frame_rate_id; |
| | 254 | break; |
| | 255 | } |
| | 256 | } |
| | 257 | if (!fr->frame_rate) { |
| | 258 | av_log(c, AV_LOG_WARNING, |
| | 259 | "Requested frame rate is not supported, using fallback.\n"); |
| | 260 | frame_rate = frame_rates.framerates[frame_rates.num - 1]; |
| | 261 | } |
| | 262 | /* Find the requested frame rate in the supported frame rates. */ |
| | 263 | for (fr = dc1394_frame_rates; fr->frame_rate; fr++) { |
| | 264 | if (fr->frame_rate_id == frame_rate) { |
| | 265 | break; |
| | 266 | } |
| | 267 | } |
| | 268 | if (!fr->frame_rate) { |
| | 269 | /* Fall back to the best rate that was listed as supported. */ |
| | 270 | av_log(c, AV_LOG_WARNING, |
| | 271 | "Requested frame rate is not available, using fallback.\n"); |
| | 272 | frame_rate = frame_rates.framerates[frame_rates.num - 1]; |
| | 273 | } |
| | 274 | } |
| | 275 | /* Get the final frame rate */ |
| | 276 | for (fr = dc1394_frame_rates; fr->frame_rate; fr++) { |
| | 277 | if (fr->frame_rate_id == frame_rate) { |
| | 278 | final_frame_rate = fr->frame_rate; |
| | 279 | break; |
| | 280 | } |
| | 281 | } |
| | 282 | |
| | 283 | /* create a video stream */ |
| | 284 | vst = av_new_stream(c, 0); |
| | 285 | if (!vst) |
| | 286 | goto out_camera; |
| | 287 | av_set_pts_info(vst, 64, 1, 1000); |
| | 288 | vst->codec->codec_type = AVMEDIA_TYPE_VIDEO; |
| | 289 | vst->codec->codec_id = CODEC_ID_RAWVIDEO; |
| | 290 | vst->codec->time_base.den = final_frame_rate; |
| | 291 | vst->codec->time_base.num = 1000; |
| | 292 | vst->codec->width = final_width; |
| | 293 | vst->codec->height = final_height; |
| | 294 | vst->codec->pix_fmt = final_pix_fmt; |
| | 295 | |
| | 296 | /* packet init */ |
| | 297 | av_init_packet(&dc1394->packet); |
| | 298 | dc1394->packet.size = avpicture_get_size(final_pix_fmt, final_width, final_height); |
| | 299 | dc1394->packet.stream_index = vst->index; |
| | 300 | dc1394->packet.flags |= AV_PKT_FLAG_KEY; |
| | 301 | |
| | 302 | dc1394->current_frame = 0; |
| | 303 | dc1394->fps = final_frame_rate; |
| | 304 | |
| | 305 | vst->codec->bit_rate = av_rescale(dc1394->packet.size * 8, final_frame_rate, 1000); |
| | 306 | |