/* * Guess the true sample aspect ratio of a video stream, * given the MPEG aspect ratio code and the actual frame size * (and the MPEG version, 1 or 2). * * Returns y4m_sar_UNKNOWN if it has no good guess. * */ y4m_ratio_t mpeg_guess_sample_aspect_ratio(int mpeg_version, mpeg_aspect_code_t code, int frame_width, int frame_height) { switch (mpeg_version) { case 1: /* MPEG-1 codes turn into SAR's, just not quite the right ones. For the common/known values, we provide the ratio used in practice, otherwise say we don't know.*/ switch (code) { case 1: return y4m_sar_SQUARE; break; case 3: return y4m_sar_PAL_16_9; break; case 6: return y4m_sar_NTSC_16_9; break; case 8: return y4m_sar_PAL_CCIR601; break; case 12: return y4m_sar_NTSC_CCIR601; break; default: return y4m_sar_UNKNOWN; break; } break; case 2: /* MPEG-2 codes turn into Display Aspect Ratios, though not exactly the DAR's used in practice. For common/standard frame sizes, we provide the original SAR; otherwise, we say we don't know. */ if (code == 1) { return y4m_sar_SQUARE; /* '1' means square *pixels* in MPEG-2 */ } else if ((code >= 2) && (code <= 4)) { return y4m_guess_sar(frame_width, frame_height, mpeg2_aspect_ratios[code]); } else { return y4m_sar_UNKNOWN; } break; default: return y4m_sar_UNKNOWN; break; } }
static int tc_y4m_open_video(Y4MPrivateData *pd, const char *filename, vob_t *vob) { int asr, ret; y4m_ratio_t framerate; y4m_ratio_t asr_rate; /* avoid fd loss in case of failed configuration */ if (pd->fd_vid == -1) { pd->fd_vid = open(filename, O_RDWR|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); if (pd->fd_vid == -1) { tc_log_error(MOD_NAME, "failed to open video stream file '%s'" " (reason: %s)", filename, strerror(errno)); return TC_ERROR; } } y4m_init_stream_info(&(pd->streaminfo)); //note: this is the real framerate of the raw stream framerate = (vob->ex_frc == 0) ?mpeg_conform_framerate(vob->ex_fps) :mpeg_framerate(vob->ex_frc); if (framerate.n == 0 && framerate.d == 0) { framerate.n = vob->ex_fps * 1000; framerate.d = 1000; } asr = (vob->ex_asr < 0) ?vob->im_asr :vob->ex_asr; tc_asr_code_to_ratio(asr, &asr_rate.n, &asr_rate.d); y4m_init_stream_info(&(pd->streaminfo)); y4m_si_set_framerate(&(pd->streaminfo), framerate); if (vob->encode_fields == TC_ENCODE_FIELDS_TOP_FIRST) { y4m_si_set_interlace(&(pd->streaminfo), Y4M_ILACE_TOP_FIRST); } else if (vob->encode_fields == TC_ENCODE_FIELDS_BOTTOM_FIRST) { y4m_si_set_interlace(&(pd->streaminfo), Y4M_ILACE_BOTTOM_FIRST); } else if (vob->encode_fields == TC_ENCODE_FIELDS_PROGRESSIVE) { y4m_si_set_interlace(&(pd->streaminfo), Y4M_ILACE_NONE); } /* XXX */ y4m_si_set_sampleaspect(&(pd->streaminfo), y4m_guess_sar(pd->width, pd->height, asr_rate)); y4m_si_set_height(&(pd->streaminfo), pd->height); y4m_si_set_width(&(pd->streaminfo), pd->width); /* Y4M_CHROMA_420JPEG 4:2:0, H/V centered, for JPEG/MPEG-1 */ /* Y4M_CHROMA_420MPEG2 4:2:0, H cosited, for MPEG-2 */ /* Y4M_CHROMA_420PALDV 4:2:0, alternating Cb/Cr, for PAL-DV */ y4m_si_set_chroma(&(pd->streaminfo), Y4M_CHROMA_420JPEG); // XXX ret = y4m_write_stream_header(pd->fd_vid, &(pd->streaminfo)); if (ret != Y4M_OK) { tc_log_warn(MOD_NAME, "failed to write video YUV4MPEG2 header: %s", y4m_strerr(ret)); return TC_ERROR; } return TC_OK; }
void writeoutYUV4MPEGheader(int out_fd, LavParam *param, EditList el, y4m_stream_info_t *streaminfo) { int n; y4m_si_set_width(streaminfo, param->output_width); y4m_si_set_height(streaminfo, param->output_height); y4m_si_set_interlace(streaminfo, param->interlace); y4m_si_set_framerate(streaminfo, mpeg_conform_framerate(el.video_fps)); if (!Y4M_RATIO_EQL(param->sar, y4m_sar_UNKNOWN)) { y4m_si_set_sampleaspect(streaminfo, param->sar); } else if ((el.video_sar_width != 0) || (el.video_sar_height != 0)) { y4m_ratio_t sar; sar.n = el.video_sar_width; sar.d = el.video_sar_height; y4m_si_set_sampleaspect(streaminfo, sar); } else { /* no idea! ...eh, just guess. */ mjpeg_warn("unspecified sample-aspect-ratio --- taking a guess..."); y4m_si_set_sampleaspect(streaminfo, y4m_guess_sar(param->output_width, param->output_height, param->dar)); } switch (el_video_frame_data_format(0, &el)) { /* FIXME: checking only 0-th frame. */ case DATAFORMAT_YUV420: switch (param->chroma) { case Y4M_UNKNOWN: case Y4M_CHROMA_420JPEG: break; case Y4M_CHROMA_420MPEG2: case Y4M_CHROMA_420PALDV: mjpeg_warn("4:2:0 chroma should be '420jpeg' with this input"); break; default: mjpeg_error_exit1("must specify 4:2:0 chroma (should be '420jpeg') with this input"); break; } break; case DATAFORMAT_YUV422: switch (param->chroma) { case Y4M_CHROMA_422: break; default: mjpeg_error_exit1("must specify chroma '422' with this input"); break; } break; case DATAFORMAT_DV2: #ifndef HAVE_LIBDV mjpeg_error_exit1("DV input was not configured at compile time"); #else el_get_video_frame(jpeg_data, 0, &el); /* FIXME: checking only 0-th frame. */ dv_parse_header(decoder, jpeg_data); switch(decoder->sampling) { case e_dv_sample_420: switch (param->chroma) { case Y4M_UNKNOWN: mjpeg_info("set chroma '420paldv' from input"); param->chroma = Y4M_CHROMA_420PALDV; break; case Y4M_CHROMA_420PALDV: break; case Y4M_CHROMA_420JPEG: case Y4M_CHROMA_420MPEG2: mjpeg_warn("4:2:0 chroma should be '420paldv' with this input"); break; case Y4M_CHROMA_422: if(libdv_pal_yv12 == 1 ) mjpeg_error_exit1("must specify 4:2:0 chroma (should be '420paldv') with this input"); break; default: mjpeg_error_exit1("must specify 4:2:0 chroma (should be '420paldv') with this input"); break; } break; case e_dv_sample_411: if (param->chroma != Y4M_CHROMA_411) mjpeg_info("chroma '411' recommended with this input"); switch (param->chroma) { case Y4M_CHROMA_420MPEG2: case Y4M_CHROMA_420PALDV: mjpeg_warn("4:2:0 chroma should be '420jpeg' with this input"); break; } break; case e_dv_sample_422: if (param->chroma != Y4M_CHROMA_422) mjpeg_info("chroma '422' recommended with this input"); switch (param->chroma) { case Y4M_CHROMA_420MPEG2: case Y4M_CHROMA_420PALDV: mjpeg_warn("4:2:0 chroma should be '420jpeg' with this input"); break; } break; default: break; } #endif break; case DATAFORMAT_MJPG: if (param->chroma != Y4M_CHROMA_422 && el.chroma == Y4M_CHROMA_422) mjpeg_info("chroma '422' recommended with this input"); switch (param->chroma) { case Y4M_CHROMA_420MPEG2: case Y4M_CHROMA_420PALDV: mjpeg_warn("4:2:0 chroma should be '420jpeg' with this input"); break; } break; } if (param->chroma == Y4M_UNKNOWN) { mjpeg_info("set default chroma '420jpeg'"); param->chroma = Y4M_CHROMA_420JPEG; } y4m_si_set_chroma(streaminfo, param->chroma); n = y4m_write_stream_header(out_fd, streaminfo); if (n != Y4M_OK) mjpeg_error("Failed to write stream header: %s", y4m_strerr(n)); }