Hello, all! I was trying to get field order autodetection working in CinelerraGG (our developer sadly died, so I can't ask him anymore ...) I get field_order like this: int FFMPEG::ff_interlace(int stream) { /* reads from demuxer because codec frame not ready */ int interlace = ffvideo[stream]->st->codecpar->field_order; printf("interlace: %i\n", interlace); switch (interlace) { case AV_FIELD_TT: return ILACE_MODE_TOP_FIRST; case AV_FIELD_BB: return ILACE_MODE_BOTTOM_FIRST; case AV_FIELD_PROGRESSIVE: return ILACE_MODE_NOTINTERLACED; default: return ILACE_MODE_UNDETECTED; } } Unfortunately, this only work for mpegts streams and not for, say, dv. I tried to add some code in libavformat/dv.c, and while it sort-of working, it apparently doesn't work early enough (at stream probe time?) in cinelerra/cinelerra-5.1/thirdparty/ffmpeg-4.3/libavformat/dv.c in function dv_extract_video_info() I added those lines (logic might be wrong, but I can fix it later, I used libavcodec/dvdec.c as example): if (c->sys->height == 720) { par->field_order = AV_FIELD_PROGRESSIVE;} else if (c->sys->height == 1080) { int ilaced = 1; int tff = (vsc_pack[3] & 0x40) == 0x40; par->field_order = tff ? AV_FIELD_TT : 0; } else { int ilaced = (vsc_pack[3] & 0x10) == 0x10; int tff = !(vsc_pack[3] & 0x40) == 0x40; par->field_order = tff ? 0 : AV_FIELD_BB; } //printf("Field order: %i \n", par->field_order); It prints 'field order: 3" for usual pal DV example, but ffprobe (from where I get my logic for extracting field_order) still says: /dev/shm/cinelerra/cinelerra-5.1/thirdparty/ffmpeg-4.3/ffprobe -show_streams /dev/shm/qt_dv_pal_test.mov Field order: 3 Field order: 3 Field order: 3 Field order: 3 Field order: 3 Field order: 3 Field order: 3 Field order: 3 Field order: 3 Field order: 3 Field order: 3 Field order: 3 Field order: 3 Field order: 3 Field order: 3 Field order: 3 Field order: 3 Field order: 3 Field order: 3 Field order: 3 Field order: 3 Field order: 3 Field order: 3 Field order: 3 Field order: 3 Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/dev/shm/qt_dv_pal_test.mov': Metadata: creation_time : 2002-10-04T18:46:28.000000Z Duration: 00:00:04.45, start: 0.000000, bitrate: 57948 kb/s Stream #0:0(eng): Video: dvvideo (dvcp / 0x70637664), yuv420p, 720x576 [SAR 16:15 DAR 4:3], 28800 kb/s, 25 fps, 25 tbr, 600 tbn, 25 tbc (default) Metadata: creation_time : 2002-10-04T18:46:28.000000Z handler_name : Apple Video Media Handler encoder : DV - PAL Stream #0:1(eng): Audio: pcm_s16le (dvca / 0x61637664), 48000 Hz, 2 channels, s16, 1536 kb/s (default) Metadata: creation_time : 2002-10-04T18:46:28.000000Z handler_name : Apple Sound Media Handler [STREAM] index=0 codec_name=dvvideo codec_long_name=DV (Digital Video) profile=unknown codec_type=video codec_time_base=1/25 codec_tag_string=dvcp codec_tag=0x70637664 width=720 height=576 coded_width=720 coded_height=576 closed_captions=0 has_b_frames=0 sample_aspect_ratio=16:15 display_aspect_ratio=4:3 pix_fmt=yuv420p level=-99 color_range=unknown color_space=unknown color_transfer=unknown color_primaries=unknown chroma_location=topleft field_order=unknown timecode=N/A [a lot more skiped] I tried to add same logic into dv_read_header(), but dv_extract_pack(frame, dv_video_control); wants 'frame' and I have no idea from where to plug it. Idea about putting this in header reading code come from libavformat/yuv4mpegdec.c Any ideas?
Stupid idea from an ignorant person (definitely wrong): It seems to me that GG has implemented media autorotation and timecode reading them in the metadata and then rotating or aligning them. Maybe also the aspect ratio or other can be read/put in the metadata? Excuse me for talking about things I don't know...
В сообщении от Sunday 15 November 2020 00:07:27 Andrea paz via Cin написал(а):
Stupid idea from an ignorant person (definitely wrong): It seems to me that GG has implemented media autorotation and timecode reading them in the metadata and then rotating or aligning them. Maybe also the aspect ratio or other can be read/put in the metadata? Excuse me for talking about things I don't know...
In my case I probably don't know how to fully initialize those structures, so only this partial form of extracting field_order from container/stream works. (I tried few other forms of accesing frame data, but they resulted in Cin segfaulting) dv codec (decoder) itself sets frame.f->interlaced_frame and frame.f->top_field_first But by time this data become avilable CinGG already probed streams and set default field order 'UNKNOW' (I think this is safe default?) I'm not sure how to force re-probing or hold filling those field until all data from decoder will be ready. I found libopenshot, it probably shows how I can improve setting our flags from libavcodec's ones (I missed two cases), but their internal organization a bit different from Cin .... http://openshot.org/files/libopenshot/FFmpegReader_8cpp_source.html // Get scan type and order from codec context/params 730 if (!check_interlace) { 731 check_interlace = true; 732 AVFieldOrder field_order = AV_GET_CODEC_ATTRIBUTES(pStream, pCodecCtx)->field_order; 733 switch(field_order) { 734 case AV_FIELD_PROGRESSIVE: 735 info.interlaced_frame = false; 736 break; 737 case AV_FIELD_TT: 738 case AV_FIELD_TB: 739 info.interlaced_frame = true; 740 info.top_field_first = true; 741 break; 742 case AV_FIELD_BT: 743 case AV_FIELD_BB: 744 info.interlaced_frame = true; 745 info.top_field_first = false; 746 break; 747 case AV_FIELD_UNKNOWN: 748 // Check again later? 749 check_interlace = false; 750 break; 751 } In my patch I omitted AV_FIELD_BT / AV_FIELD_TB (those exist because apparently fields can be coded and displayed in different order!) Code in ffprobe was: static int show_stream(WriterContext *w, AVFormatContext *fmt_ctx, int stream_idx, InputStream *ist, int in_program) { AVStream *stream = ist->st; AVCodecParameters *par; AVCodecContext *dec_ctx; char val_str[128]; const char *s; AVRational sar, dar; AVBPrint pbuf; const AVCodecDescriptor *cd; int ret = 0; const char *profile = NULL; par = stream->codecpar; [skip a lot] if (par->field_order == AV_FIELD_PROGRESSIVE) print_str("field_order", "progressive"); else if (par->field_order == AV_FIELD_TT) print_str("field_order", "tt"); else if (par->field_order == AV_FIELD_BB) print_str("field_order", "bb"); else if (par->field_order == AV_FIELD_TB) print_str("field_order", "tb"); else if (par->field_order == AV_FIELD_BT) print_str("field_order", "bt"); else print_str_opt("field_order", "unknown"); BUT there was another isntance of field reporting: static void show_frame(WriterContext *w, AVFrame *frame, AVStream *stream, AVFormatContext *fmt_ctx) { AVBPrint pbuf; char val_str[128]; const char *s; int i; [skip] case AVMEDIA_TYPE_VIDEO: print_int("width", frame->width); print_int("height", frame->height); s = av_get_pix_fmt_name(frame->format); if (s) print_str ("pix_fmt", s); else print_str_opt("pix_fmt", "unknown"); sar = av_guess_sample_aspect_ratio(fmt_ctx, stream, frame); if (sar.num) { print_q("sample_aspect_ratio", sar, ':'); } else { print_str_opt("sample_aspect_ratio", "N/A"); } print_fmt("pict_type", "%c", av_get_picture_type_char(frame->pict_type)); print_int("coded_picture_number", frame->coded_picture_number); print_int("display_picture_number", frame->display_picture_number); print_int("interlaced_frame", frame->interlaced_frame); print_int("top_field_first", frame->top_field_first); print_int("repeat_pict", frame->repeat_pict); BUT I currently have no idea how to say Cin to not fill interlacing type after stream probe says 'unknown' and wait until codec frame probe will give correct info.
participants (2)
-
Andrea paz -
Andrew Randrianasulu